// Copyright 2018 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.

//go:build amd64
// +build amd64

package runtime

import "unsafe"

const (
	debugCallSystemStack = "executing on Go runtime stack"
	debugCallUnknownFunc = "call from unknown function"
	debugCallRuntime     = "call from within the Go runtime"
	debugCallUnsafePoint = "call not at safe point"
)

func debugCallV1()
func debugCallPanicked(val interface{})

// debugCallCheck checks whether it is safe to inject a debugger
// function call with return PC pc. If not, it returns a string
// explaining why.
//
//go:nosplit
func debugCallCheck(pc uintptr) string {
	// No user calls from the system stack.
	if getg() != getg().m.curg {
		return debugCallSystemStack
	}
	if sp := getcallersp(); !(getg().stack.lo < sp && sp <= getg().stack.hi) {
		// Fast syscalls (nanotime) and racecall switch to the
		// g0 stack without switching g. We can't safely make
		// a call in this state. (We can't even safely
		// systemstack.)
		return debugCallSystemStack
	}

	// Switch to the system stack to avoid overflowing the user
	// stack.
	var ret string
	systemstack(func() {
		f := findfunc(pc)
		if !f.valid() {
			ret = debugCallUnknownFunc
			return
		}

		name := funcname(f)

		switch name {
		case "debugCall32",
			"debugCall64",
			"debugCall128",
			"debugCall256",
			"debugCall512",
			"debugCall1024",
			"debugCall2048",
			"debugCall4096",
			"debugCall8192",
			"debugCall16384",
			"debugCall32768",
			"debugCall65536":
			// These functions are allowed so that the debugger can initiate multiple function calls.
			// See: https://golang.org/cl/161137/
			return
		}

		// Disallow calls from the runtime. We could
		// potentially make this condition tighter (e.g., not
		// when locks are held), but there are enough tightly
		// coded sequences (e.g., defer handling) that it's
		// better to play it safe.
		if pfx := "runtime."; len(name) > len(pfx) && name[:len(pfx)] == pfx {
			ret = debugCallRuntime
			return
		}

		// Check that this isn't an unsafe-point.
		if pc != f.entry {
			pc--
		}
		up := pcdatavalue(f, _PCDATA_UnsafePoint, pc, nil)
		if up != _PCDATA_UnsafePointSafe {
			// Not at a safe point.
			ret = debugCallUnsafePoint
		}
	})
	return ret
}

// debugCallWrap starts a new goroutine to run a debug call and blocks
// the calling goroutine. On the goroutine, it prepares to recover
// panics from the debug call, and then calls the call dispatching
// function at PC dispatch.
//
// This must be deeply nosplit because there are untyped values on the
// stack from debugCallV1.
//
//go:nosplit
func debugCallWrap(dispatch uintptr) {
	var lockedm bool
	var lockedExt uint32
	callerpc := getcallerpc()
	gp := getg()

	// Create a new goroutine to execute the call on. Run this on
	// the system stack to avoid growing our stack.
	systemstack(func() {
		var args struct {
			dispatch uintptr
			callingG *g
		}
		args.dispatch = dispatch
		args.callingG = gp
		fn := debugCallWrap1
		newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), unsafe.Pointer(&args), int32(unsafe.Sizeof(args)), gp, callerpc)

		// If the current G is locked, then transfer that
		// locked-ness to the new goroutine.
		if gp.lockedm != 0 {
			// Save lock state to restore later.
			mp := gp.m
			if mp != gp.lockedm.ptr() {
				throw("inconsistent lockedm")
			}

			lockedm = true
			lockedExt = mp.lockedExt

			// Transfer external lock count to internal so
			// it can't be unlocked from the debug call.
			mp.lockedInt++
			mp.lockedExt = 0

			mp.lockedg.set(newg)
			newg.lockedm.set(mp)
			gp.lockedm = 0
		}

		// Mark the calling goroutine as being at an async
		// safe-point, since it has a few conservative frames
		// at the bottom of the stack. This also prevents
		// stack shrinks.
		gp.asyncSafePoint = true

		// Stash newg away so we can execute it below (mcall's
		// closure can't capture anything).
		gp.schedlink.set(newg)
	})

	// Switch to the new goroutine.
	mcall(func(gp *g) {
		// Get newg.
		newg := gp.schedlink.ptr()
		gp.schedlink = 0

		// Park the calling goroutine.
		gp.waitreason = waitReasonDebugCall
		if trace.enabled {
			traceGoPark(traceEvGoBlock, 1)
		}
		casgstatus(gp, _Grunning, _Gwaiting)
		dropg()

		// Directly execute the new goroutine. The debug
		// protocol will continue on the new goroutine, so
		// it's important we not just let the scheduler do
		// this or it may resume a different goroutine.
		execute(newg, true)
	})

	// We'll resume here when the call returns.

	// Restore locked state.
	if lockedm {
		mp := gp.m
		mp.lockedExt = lockedExt
		mp.lockedInt--
		mp.lockedg.set(gp)
		gp.lockedm.set(mp)
	}

	gp.asyncSafePoint = false
}

// debugCallWrap1 is the continuation of debugCallWrap on the callee
// goroutine.
func debugCallWrap1(dispatch uintptr, callingG *g) {
	// Dispatch call and trap panics.
	debugCallWrap2(dispatch)

	// Resume the caller goroutine.
	getg().schedlink.set(callingG)
	mcall(func(gp *g) {
		callingG := gp.schedlink.ptr()
		gp.schedlink = 0

		// Unlock this goroutine from the M if necessary. The
		// calling G will relock.
		if gp.lockedm != 0 {
			gp.lockedm = 0
			gp.m.lockedg = 0
		}

		// Switch back to the calling goroutine. At some point
		// the scheduler will schedule us again and we'll
		// finish exiting.
		if trace.enabled {
			traceGoSched()
		}
		casgstatus(gp, _Grunning, _Grunnable)
		dropg()
		lock(&sched.lock)
		globrunqput(gp)
		unlock(&sched.lock)

		if trace.enabled {
			traceGoUnpark(callingG, 0)
		}
		casgstatus(callingG, _Gwaiting, _Grunnable)
		execute(callingG, true)
	})
}

func debugCallWrap2(dispatch uintptr) {
	// Call the dispatch function and trap panics.
	var dispatchF func()
	dispatchFV := funcval{dispatch}
	*(*unsafe.Pointer)(unsafe.Pointer(&dispatchF)) = noescape(unsafe.Pointer(&dispatchFV))

	var ok bool
	defer func() {
		if !ok {
			err := recover()
			debugCallPanicked(err)
		}
	}()
	dispatchF()
	ok = true
}
