#include <linux/sched.h>
#include <linux/ftrace.h>
#include <asm/ptrace.h>
#include <asm/bitops.h>
#include <asm/stacktrace.h>
#include <asm/unwind.h>

unsigned long unwind_get_return_address(struct unwind_state *state)
{
	unsigned long addr;

	if (unwind_done(state))
		return 0;

	addr = READ_ONCE_NOCHECK(*state->sp);

	return ftrace_graph_ret_addr(state->task, &state->graph_idx,
				     addr, state->sp);
}
EXPORT_SYMBOL_GPL(unwind_get_return_address);

bool unwind_next_frame(struct unwind_state *state)
{
	struct stack_info *info = &state->stack_info;

	if (unwind_done(state))
		return false;

	do {
		for (state->sp++; state->sp < info->end; state->sp++) {
			unsigned long addr = READ_ONCE_NOCHECK(*state->sp);

			if (__kernel_text_address(addr))
				return true;
		}

		state->sp = PTR_ALIGN(info->next_sp, sizeof(long));

	} while (!get_stack_info(state->sp, state->task, info,
				 &state->stack_mask));

	return false;
}
EXPORT_SYMBOL_GPL(unwind_next_frame);

void __unwind_start(struct unwind_state *state, struct task_struct *task,
		    struct pt_regs *regs, unsigned long *first_frame)
{
	memset(state, 0, sizeof(*state));

	state->task = task;
	state->sp   = PTR_ALIGN(first_frame, sizeof(long));

	get_stack_info(first_frame, state->task, &state->stack_info,
		       &state->stack_mask);

	/*
	 * The caller can provide the address of the first frame directly
	 * (first_frame) or indirectly (regs->sp) to indicate which stack frame
	 * to start unwinding at.  Skip ahead until we reach it.
	 */
	if (!unwind_done(state) &&
	    (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
	    !__kernel_text_address(*first_frame)))
		unwind_next_frame(state);
}
EXPORT_SYMBOL_GPL(__unwind_start);
