// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022 Loongson Technology Corporation Limited
 */
#include <linux/kallsyms.h>

#include <asm/inst.h>
#include <asm/ptrace.h>
#include <asm/unwind.h>

unsigned long unwind_get_return_address(struct unwind_state *state)
{

	if (unwind_done(state))
		return 0;
	else if (state->type)
		return state->pc;
	else if (state->first)
		return state->pc;

	return *(unsigned long *)(state->sp);

}
EXPORT_SYMBOL_GPL(unwind_get_return_address);

static bool unwind_by_guess(struct unwind_state *state)
{
	struct stack_info *info = &state->stack_info;
	unsigned long addr;

	for (state->sp += sizeof(unsigned long);
	     state->sp < info->end;
	     state->sp += sizeof(unsigned long)) {
		addr = *(unsigned long *)(state->sp);
		if (__kernel_text_address(addr))
			return true;
	}

	return false;
}

static bool unwind_by_prologue(struct unwind_state *state)
{
	struct stack_info *info = &state->stack_info;
	union loongarch_instruction *ip, *ip_end;
	unsigned long frame_size = 0, frame_ra = -1;
	unsigned long size, offset, pc = state->pc;

	if (state->sp >= info->end || state->sp < info->begin)
		return false;

	if (!kallsyms_lookup_size_offset(pc, &size, &offset))
		return false;

	ip = (union loongarch_instruction *)(pc - offset);
	ip_end = (union loongarch_instruction *)pc;

	while (ip < ip_end) {
		if (is_stack_alloc_ins(ip)) {
			frame_size = (1 << 12) - ip->reg2i12_format.immediate;
			ip++;
			break;
		}
		ip++;
	}

	if (!frame_size) {
		if (state->first)
			goto first;

		return false;
	}

	while (ip < ip_end) {
		if (is_ra_save_ins(ip)) {
			frame_ra = ip->reg2i12_format.immediate;
			break;
		}
		if (is_branch_ins(ip))
			break;
		ip++;
	}

	if (frame_ra < 0) {
		if (state->first) {
			state->sp = state->sp + frame_size;
			goto first;
		}
		return false;
	}

	if (state->first)
		state->first = false;

	state->pc = *(unsigned long *)(state->sp + frame_ra);
	state->sp = state->sp + frame_size;
	return !!__kernel_text_address(state->pc);

first:
	state->first = false;
	if (state->pc == state->ra)
		return false;

	state->pc = state->ra;

	return !!__kernel_text_address(state->ra);
}

void unwind_start(struct unwind_state *state, struct task_struct *task,
		    struct pt_regs *regs)
{
	memset(state, 0, sizeof(*state));

	if (regs &&  __kernel_text_address(regs->csr_era)) {
		state->pc = regs->csr_era;
		state->sp = regs->regs[3];
		state->ra = regs->regs[1];
		state->type = UNWINDER_PROLOGUE;
	}

	state->task = task;
	state->first = true;

	get_stack_info(state->sp, state->task, &state->stack_info);

	if (!unwind_done(state) && !__kernel_text_address(state->pc))
		unwind_next_frame(state);
}
EXPORT_SYMBOL_GPL(unwind_start);

bool unwind_next_frame(struct unwind_state *state)
{
	struct stack_info *info = &state->stack_info;
	struct pt_regs *regs;
	unsigned long pc;

	if (unwind_done(state))
		return false;

	do {
		switch (state->type) {
		case UNWINDER_GUESS:
			state->first = false;
			if (unwind_by_guess(state))
				return true;
			break;

		case UNWINDER_PROLOGUE:
			if (unwind_by_prologue(state))
				return true;

			if (info->type == STACK_TYPE_IRQ &&
				info->end == state->sp) {
				regs = (struct pt_regs *)info->next_sp;
				pc = regs->csr_era;

				if (user_mode(regs) || !__kernel_text_address(pc))
					return false;

				state->pc = pc;
				state->sp = regs->regs[3];
				state->ra = regs->regs[1];
				state->first = true;
				get_stack_info(state->sp, state->task, info);

				return true;
			}
		}

		state->sp = info->next_sp;

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

	return false;
}
EXPORT_SYMBOL_GPL(unwind_next_frame);
