// SPDX-License-Identifier: GPL-2.0
/*
* Generic interfaces for unwinding user space
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/unwind_user.h>
#include <linux/uaccess.h>

#define for_each_user_frame(state) \
	for (unwind_user_start(state); !(state)->done; unwind_user_next(state))

static inline int
get_user_word(unsigned long *word, unsigned long base, int off, unsigned int ws)
{
	unsigned long __user *addr = (void __user *)base + off;
#ifdef CONFIG_COMPAT
	if (ws == sizeof(int)) {
		unsigned int data;
		int ret = get_user(data, (unsigned int __user *)addr);
		*word = data;
		return ret;
	}
#endif
	return get_user(*word, addr);
}

static int unwind_user_next_common(struct unwind_user_state *state,
				   const struct unwind_user_frame *frame)
{
	unsigned long cfa, fp, ra;

	/* Get the Canonical Frame Address (CFA) */
	if (frame->use_fp) {
		if (state->fp < state->sp)
			return -EINVAL;
		cfa = state->fp;
	} else {
		cfa = state->sp;
	}
	cfa += frame->cfa_off;

	/* Make sure that stack is not going in wrong direction */
	if (cfa <= state->sp)
		return -EINVAL;

	/* Make sure that the address is word aligned */
	if (cfa & (state->ws - 1))
		return -EINVAL;

	/* Get the Return Address (RA) */
	if (get_user_word(&ra, cfa, frame->ra_off, state->ws))
		return -EINVAL;

	/* Get the Frame Pointer (FP) */
	if (frame->fp_off && get_user_word(&fp, cfa, frame->fp_off, state->ws))
		return -EINVAL;

	state->ip = ra;
	state->sp = cfa;
	if (frame->fp_off)
		state->fp = fp;
	state->topmost = false;
	return 0;
}

static int unwind_user_next_fp(struct unwind_user_state *state)
{
	struct pt_regs *regs = task_pt_regs(current);

	if (state->topmost && unwind_user_at_function_start(regs)) {
		const struct unwind_user_frame fp_entry_frame = {
			ARCH_INIT_USER_FP_ENTRY_FRAME(state->ws)
		};
		return unwind_user_next_common(state, &fp_entry_frame);
	}

	const struct unwind_user_frame fp_frame = {
		ARCH_INIT_USER_FP_FRAME(state->ws)
	};
	return unwind_user_next_common(state, &fp_frame);
}

static int unwind_user_next(struct unwind_user_state *state)
{
	unsigned long iter_mask = state->available_types;
	unsigned int bit;

	if (state->done)
		return -EINVAL;

	for_each_set_bit(bit, &iter_mask, NR_UNWIND_USER_TYPE_BITS) {
		enum unwind_user_type type = BIT(bit);

		state->current_type = type;
		switch (type) {
		case UNWIND_USER_TYPE_FP:
			if (!unwind_user_next_fp(state))
				return 0;
			continue;
		default:
			WARN_ONCE(1, "Undefined unwind bit %d", bit);
			break;
		}
		break;
	}

	/* No successful unwind method. */
	state->current_type = UNWIND_USER_TYPE_NONE;
	state->done = true;
	return -EINVAL;
}

static int unwind_user_start(struct unwind_user_state *state)
{
	struct pt_regs *regs = task_pt_regs(current);

	memset(state, 0, sizeof(*state));

	if ((current->flags & PF_KTHREAD) || !user_mode(regs)) {
		state->done = true;
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_HAVE_UNWIND_USER_FP))
		state->available_types |= UNWIND_USER_TYPE_FP;

	state->ip = instruction_pointer(regs);
	state->sp = user_stack_pointer(regs);
	state->fp = frame_pointer(regs);
	state->ws = unwind_user_word_size(regs);
	if (!state->ws) {
		state->done = true;
		return -EINVAL;
	}
	state->topmost = true;

	return 0;
}

int unwind_user(struct unwind_stacktrace *trace, unsigned int max_entries)
{
	struct unwind_user_state state;

	trace->nr = 0;

	if (!max_entries)
		return -EINVAL;

	if (current->flags & PF_KTHREAD)
		return 0;

	for_each_user_frame(&state) {
		trace->entries[trace->nr++] = state.ip;
		if (trace->nr >= max_entries)
			break;
	}

	return 0;
}
