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

package ld

import (
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/link/internal/loader"
	"fmt"
	"internal/buildcfg"
	"sort"
	"strings"
)

type stackCheck struct {
	ctxt      *Link
	ldr       *loader.Loader
	morestack loader.Sym
	callSize  int // The number of bytes added by a CALL

	// height records the maximum number of bytes a function and
	// its callees can add to the stack without a split check.
	height map[loader.Sym]int16

	// graph records the out-edges from each symbol. This is only
	// populated on a second pass if the first pass reveals an
	// over-limit function.
	graph map[loader.Sym][]stackCheckEdge
}

type stackCheckEdge struct {
	growth int        // Stack growth in bytes at call to target
	target loader.Sym // 0 for stack growth without a call
}

// stackCheckCycle is a sentinel stored in the height map to detect if
// we've found a cycle. This is effectively an "infinite" stack
// height, so we use the closest value to infinity that we can.
const stackCheckCycle int16 = 1<<15 - 1

// stackCheckIndirect is a sentinel Sym value used to represent the
// target of an indirect/closure call.
const stackCheckIndirect loader.Sym = ^loader.Sym(0)

// doStackCheck walks the call tree to check that there is always
// enough stack space for call frames, especially for a chain of
// nosplit functions.
//
// It walks all functions to accumulate the number of bytes they can
// grow the stack by without a split check and checks this against the
// limit.
func (ctxt *Link) doStackCheck() {
	sc := newStackCheck(ctxt, false)

	// limit is number of bytes a splittable function ensures are
	// available on the stack. If any call chain exceeds this
	// depth, the stack check test fails.
	//
	// The call to morestack in every splittable function ensures
	// that there are at least StackLimit bytes available below SP
	// when morestack returns.
	limit := objabi.StackNosplit(*flagRace) - sc.callSize
	if buildcfg.GOARCH == "arm64" {
		// Need an extra 8 bytes below SP to save FP.
		limit -= 8
	}

	// Compute stack heights without any back-tracking information.
	// This will almost certainly succeed and we can simply
	// return. If it fails, we do a second pass with back-tracking
	// to produce a good error message.
	//
	// This accumulates stack heights bottom-up so it only has to
	// visit every function once.
	var failed []loader.Sym
	for _, s := range ctxt.Textp {
		if sc.check(s) > limit {
			failed = append(failed, s)
		}
	}

	if len(failed) > 0 {
		// Something was over-limit, so now we do the more
		// expensive work to report a good error. First, for
		// the over-limit functions, redo the stack check but
		// record the graph this time.
		sc = newStackCheck(ctxt, true)
		for _, s := range failed {
			sc.check(s)
		}

		// Find the roots of the graph (functions that are not
		// called by any other function).
		roots := sc.findRoots()

		// Find and report all paths that go over the limit.
		// This accumulates stack depths top-down. This is
		// much less efficient because we may have to visit
		// the same function multiple times at different
		// depths, but lets us find all paths.
		for _, root := range roots {
			ctxt.Errorf(root, "nosplit stack over %d byte limit", limit)
			chain := []stackCheckChain{{stackCheckEdge{0, root}, false}}
			sc.report(root, limit, &chain)
		}
	}
}

func newStackCheck(ctxt *Link, graph bool) *stackCheck {
	sc := &stackCheck{
		ctxt:      ctxt,
		ldr:       ctxt.loader,
		morestack: ctxt.loader.Lookup("runtime.morestack", 0),
		height:    make(map[loader.Sym]int16, len(ctxt.Textp)),
	}
	// Compute stack effect of a CALL operation. 0 on LR machines.
	// 1 register pushed on non-LR machines.
	if !ctxt.Arch.HasLR {
		sc.callSize = ctxt.Arch.RegSize
	}

	if graph {
		// We're going to record the call graph.
		sc.graph = make(map[loader.Sym][]stackCheckEdge)
	}

	return sc
}

func (sc *stackCheck) symName(sym loader.Sym) string {
	switch sym {
	case stackCheckIndirect:
		return "indirect"
	case 0:
		return "leaf"
	}
	return fmt.Sprintf("%s<%d>", sc.ldr.SymName(sym), sc.ldr.SymVersion(sym))
}

// check returns the stack height of sym. It populates sc.height and
// sc.graph for sym and every function in its call tree.
func (sc *stackCheck) check(sym loader.Sym) int {
	if h, ok := sc.height[sym]; ok {
		// We've already visited this symbol or we're in a cycle.
		return int(h)
	}
	// Store the sentinel so we can detect cycles.
	sc.height[sym] = stackCheckCycle
	// Compute and record the height and optionally edges.
	h, edges := sc.computeHeight(sym, *flagDebugNosplit || sc.graph != nil)
	if h > int(stackCheckCycle) { // Prevent integer overflow
		h = int(stackCheckCycle)
	}
	sc.height[sym] = int16(h)
	if sc.graph != nil {
		sc.graph[sym] = edges
	}

	if *flagDebugNosplit {
		for _, edge := range edges {
			fmt.Printf("nosplit: %s +%d", sc.symName(sym), edge.growth)
			if edge.target == 0 {
				// Local stack growth or leaf function.
				fmt.Printf("\n")
			} else {
				fmt.Printf(" -> %s\n", sc.symName(edge.target))
			}
		}
	}

	return h
}

// computeHeight returns the stack height of sym. If graph is true, it
// also returns the out-edges of sym.
//
// Caching is applied to this in check. Call check instead of calling
// this directly.
func (sc *stackCheck) computeHeight(sym loader.Sym, graph bool) (int, []stackCheckEdge) {
	ldr := sc.ldr

	// Check special cases.
	if sym == sc.morestack {
		// morestack looks like it calls functions, but they
		// either happen only when already on the system stack
		// (where there is ~infinite space), or after
		// switching to the system stack. Hence, its stack
		// height on the user stack is 0.
		return 0, nil
	}
	if sym == stackCheckIndirect {
		// Assume that indirect/closure calls are always to
		// splittable functions, so they just need enough room
		// to call morestack.
		return sc.callSize, []stackCheckEdge{{sc.callSize, sc.morestack}}
	}

	// Ignore calls to external functions. Assume that these calls
	// are only ever happening on the system stack, where there's
	// plenty of room.
	if ldr.AttrExternal(sym) {
		return 0, nil
	}
	if info := ldr.FuncInfo(sym); !info.Valid() { // also external
		return 0, nil
	}

	// Track the maximum height of this function and, if we're
	// recording the graph, its out-edges.
	var edges []stackCheckEdge
	maxHeight := 0
	ctxt := sc.ctxt
	// addEdge adds a stack growth out of this function to
	// function "target" or, if target == 0, a local stack growth
	// within the function.
	addEdge := func(growth int, target loader.Sym) {
		if graph {
			edges = append(edges, stackCheckEdge{growth, target})
		}
		height := growth
		if target != 0 { // Don't walk into the leaf "edge"
			height += sc.check(target)
		}
		if height > maxHeight {
			maxHeight = height
		}
	}

	if !ldr.IsNoSplit(sym) {
		// Splittable functions start with a call to
		// morestack, after which their height is 0. Account
		// for the height of the call to morestack.
		addEdge(sc.callSize, sc.morestack)
		return maxHeight, edges
	}

	// This function is nosplit, so it adjusts SP without a split
	// check.
	//
	// Walk through SP adjustments in function, consuming relocs
	// and following calls.
	maxLocalHeight := 0
	relocs, ri := ldr.Relocs(sym), 0
	pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
	for pcsp.Init(ldr.Data(ldr.Pcsp(sym))); !pcsp.Done; pcsp.Next() {
		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
		height := int(pcsp.Value)
		if height > maxLocalHeight {
			maxLocalHeight = height
		}

		// Process calls in this span.
		for ; ri < relocs.Count(); ri++ {
			r := relocs.At(ri)
			if uint32(r.Off()) >= pcsp.NextPC {
				break
			}
			t := r.Type()
			if t.IsDirectCall() || t == objabi.R_CALLIND {
				growth := height + sc.callSize
				var target loader.Sym
				if t == objabi.R_CALLIND {
					target = stackCheckIndirect
				} else {
					target = r.Sym()
				}
				addEdge(growth, target)
			}
		}
	}
	if maxLocalHeight > maxHeight {
		// This is either a leaf function, or the function
		// grew its stack to larger than the maximum call
		// height between calls. Either way, record that local
		// stack growth.
		addEdge(maxLocalHeight, 0)
	}

	return maxHeight, edges
}

func (sc *stackCheck) findRoots() []loader.Sym {
	// Collect all nodes.
	nodes := make(map[loader.Sym]struct{})
	for k := range sc.graph {
		nodes[k] = struct{}{}
	}

	// Start a DFS from each node and delete all reachable
	// children. If we encounter an unrooted cycle, this will
	// delete everything in that cycle, so we detect this case and
	// track the lowest-numbered node encountered in the cycle and
	// put that node back as a root.
	var walk func(origin, sym loader.Sym) (cycle bool, lowest loader.Sym)
	walk = func(origin, sym loader.Sym) (cycle bool, lowest loader.Sym) {
		if _, ok := nodes[sym]; !ok {
			// We already deleted this node.
			return false, 0
		}
		delete(nodes, sym)

		if origin == sym {
			// We found an unrooted cycle. We already
			// deleted all children of this node. Walk
			// back up, tracking the lowest numbered
			// symbol in this cycle.
			return true, sym
		}

		// Delete children of this node.
		for _, out := range sc.graph[sym] {
			if c, l := walk(origin, out.target); c {
				cycle = true
				if lowest == 0 {
					// On first cycle detection,
					// add sym to the set of
					// lowest-numbered candidates.
					lowest = sym
				}
				if l < lowest {
					lowest = l
				}
			}
		}
		return
	}
	for k := range nodes {
		// Delete all children of k.
		for _, out := range sc.graph[k] {
			if cycle, lowest := walk(k, out.target); cycle {
				// This is an unrooted cycle so we
				// just deleted everything. Put back
				// the lowest-numbered symbol.
				nodes[lowest] = struct{}{}
			}
		}
	}

	// Sort roots by height. This makes the result deterministic
	// and also improves the error reporting.
	var roots []loader.Sym
	for k := range nodes {
		roots = append(roots, k)
	}
	sort.Slice(roots, func(i, j int) bool {
		h1, h2 := sc.height[roots[i]], sc.height[roots[j]]
		if h1 != h2 {
			return h1 > h2
		}
		// Secondary sort by Sym.
		return roots[i] < roots[j]
	})
	return roots
}

type stackCheckChain struct {
	stackCheckEdge
	printed bool
}

func (sc *stackCheck) report(sym loader.Sym, depth int, chain *[]stackCheckChain) {
	// Walk the out-edges of sym. We temporarily pull the edges
	// out of the graph to detect cycles and prevent infinite
	// recursion.
	edges, ok := sc.graph[sym]
	isCycle := !(ok || sym == 0)
	delete(sc.graph, sym)
	for _, out := range edges {
		*chain = append(*chain, stackCheckChain{out, false})
		sc.report(out.target, depth-out.growth, chain)
		*chain = (*chain)[:len(*chain)-1]
	}
	sc.graph[sym] = edges

	// If we've reached the end of a chain and it went over the
	// stack limit or was a cycle that would eventually go over,
	// print the whole chain.
	//
	// We should either be in morestack (which has no out-edges)
	// or the sentinel 0 Sym "called" from a leaf function (which
	// has no out-edges), or we came back around a cycle (possibly
	// to ourselves) and edges was temporarily nil'd.
	if len(edges) == 0 && (depth < 0 || isCycle) {
		var indent string
		for i := range *chain {
			ent := &(*chain)[i]
			if ent.printed {
				// Already printed on an earlier part
				// of this call tree.
				continue
			}
			ent.printed = true

			if i == 0 {
				// chain[0] is just the root function,
				// not a stack growth.
				fmt.Printf("%s\n", sc.symName(ent.target))
				continue
			}

			indent = strings.Repeat("    ", i)
			fmt.Print(indent)
			// Grows the stack X bytes and (maybe) calls Y.
			fmt.Printf("grows %d bytes", ent.growth)
			if ent.target == 0 {
				// Not a call, just a leaf. Print nothing.
			} else {
				fmt.Printf(", calls %s", sc.symName(ent.target))
			}
			fmt.Printf("\n")
		}
		// Print how far over this chain went.
		if isCycle {
			fmt.Printf("%sinfinite cycle\n", indent)
		} else {
			fmt.Printf("%s%d bytes over limit\n", indent, -depth)
		}
	}
}
