// SPDX-License-Identifier: GPL-2.0
#include "libunwind-arch.h"
#include "../debug.h"
#include "../maps.h"
#include "../thread.h"
#include "../../../arch/arm/include/uapi/asm/perf_regs.h"
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
#include <elf.h>
#include <errno.h>

#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
#include <libunwind-arm.h>
#endif

int __get_perf_regnum_for_unw_regnum_arm(int unw_regnum)
{
	if (unw_regnum < 0 || unw_regnum >= PERF_REG_ARM_MAX) {
		pr_err("unwind: invalid reg id %d\n", unw_regnum);
		return -EINVAL;
	}
	return unw_regnum;
}

void __libunwind_arch__flush_access_arm(struct maps *maps __maybe_unused)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	unw_flush_cache(maps__addr_space(maps), 0, 0);
#endif
}

void __libunwind_arch__finish_access_arm(struct maps *maps __maybe_unused)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	unw_destroy_addr_space(maps__addr_space(maps));
#endif
}


#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
			  int need_unwind_info, void *arg)
{
	return __libunwind__find_proc_info(as, ip, pi, need_unwind_info, arg);
}

static void put_unwind_info(unw_addr_space_t __maybe_unused as,
			    unw_proc_info_t *pi __maybe_unused,
			    void *arg __maybe_unused)
{
	pr_debug("unwind: put_unwind_info called\n");
}

static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
				  unw_word_t __maybe_unused *dil_addr,
				  void __maybe_unused *arg)
{
	return -UNW_ENOINFO;
}

static int access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *valp,
		      int __write, void *arg)
{
	return __libunwind__access_mem(as, addr, valp, __write, arg);
}

static int access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp,
		      int __write, void *arg)
{
	return __libunwind__access_reg(as, regnum, valp, __write, arg);
}

static int access_fpreg(unw_addr_space_t __maybe_unused as,
			unw_regnum_t __maybe_unused num,
			unw_fpreg_t __maybe_unused *val,
			int __maybe_unused __write,
			void __maybe_unused *arg)
{
	pr_err("unwind: access_fpreg unsupported\n");
	return -UNW_EINVAL;
}

static int resume(unw_addr_space_t __maybe_unused as,
		  unw_cursor_t __maybe_unused *cu,
		  void __maybe_unused *arg)
{
	pr_err("unwind: resume unsupported\n");
	return -UNW_EINVAL;
}

static int get_proc_name(unw_addr_space_t __maybe_unused as,
			 unw_word_t __maybe_unused addr,
			 char __maybe_unused *bufp, size_t __maybe_unused buf_len,
			 unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
{
	pr_err("unwind: get_proc_name unsupported\n");
	return -UNW_EINVAL;
}
#endif

void *__libunwind_arch__create_addr_space_arm(void)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	static unw_accessors_t accessors = {
		.find_proc_info		= find_proc_info,
		.put_unwind_info	= put_unwind_info,
		.get_dyn_info_list_addr	= get_dyn_info_list_addr,
		.access_mem		= access_mem,
		.access_reg		= access_reg,
		.access_fpreg		= access_fpreg,
		.resume			= resume,
		.get_proc_name		= get_proc_name,
	};
	unw_addr_space_t addr_space;

	addr_space = unw_create_addr_space(&accessors, /*byte_order=*/0);
	unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
	return addr_space;
#else
	return NULL;
#endif
}

#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
					       unw_word_t ip,
					       unw_dyn_info_t *di,
					       unw_proc_info_t *pi,
					       int need_unwind_info, void *arg);
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
#endif

int __libunwind_arch__dwarf_search_unwind_table_arm(void *as __maybe_unused,
						       uint64_t ip __maybe_unused,
						       struct libarch_unwind__dyn_info *_di __maybe_unused,
						       void *pi __maybe_unused,
						       int need_unwind_info __maybe_unused,
						       void *arg __maybe_unused)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	unw_dyn_info_t di = {
		.format     = UNW_INFO_FORMAT_REMOTE_TABLE,
		.start_ip   = _di->start_ip,
		.end_ip     = _di->end_ip,
		.u = {
			.rti = {
				.segbase    = _di->segbase,
				.table_data = _di->table_data,
				.table_len  = _di->table_len,
			},
		},
	};
	int ret = dwarf_search_unwind_table(as, ip, &di, pi, need_unwind_info, arg);

	_di->start_ip = di.start_ip;
	_di->end_ip = di.end_ip;
	_di->segbase = di.u.rti.segbase;
	_di->table_data = di.u.rti.table_data;
	_di->table_len = di.u.rti.table_len;
	return ret;
#else
	return -EINVAL;
#endif
}

#if defined(HAVE_LIBUNWIND_ARM_SUPPORT) && !defined(NO_LIBUNWIND_DEBUG_FRAME_ARM)
extern int UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
					    unw_word_t ip,
					    unw_word_t segbase,
					    const char *obj_name, unw_word_t start,
					    unw_word_t end);
#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
#endif

int __libunwind_arch__dwarf_find_debug_frame_arm(int found __maybe_unused,
						 struct libarch_unwind__dyn_info *_di __maybe_unused,
						 uint64_t ip __maybe_unused,
						 uint64_t segbase __maybe_unused,
						 const char *obj_name __maybe_unused,
						 uint64_t start __maybe_unused,
						 uint64_t end __maybe_unused)
{
#if defined(HAVE_LIBUNWIND_ARM_SUPPORT) && !defined(NO_LIBUNWIND_DEBUG_FRAME_ARM)
	unw_dyn_info_t di = {
		.format     = UNW_INFO_FORMAT_REMOTE_TABLE,
		.start_ip   = _di->start_ip,
		.end_ip     = _di->end_ip,
		.u = {
			.rti = {
				.segbase    = _di->segbase,
				.table_data = _di->table_data,
				.table_len  = _di->table_len,
			},
		},
	};
	int ret = dwarf_find_debug_frame(found, &di, ip, segbase, obj_name, start, end);

	_di->start_ip = di.start_ip;
	_di->end_ip = di.end_ip;
	_di->segbase = di.u.ti.segbase;
	_di->table_data = di.u.ti.table_data;
	_di->table_len = di.u.ti.table_len;
	return ret;
#else
	return -EINVAL;
#endif
}

struct unwind_info *__libunwind_arch_unwind_info__new_arm(struct thread *thread __maybe_unused,
							     struct perf_sample *sample  __maybe_unused,
							     int max_stack __maybe_unused,
							     bool best_effort  __maybe_unused,
							     uint64_t first_ip  __maybe_unused)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	struct arch_unwind_info {
		struct unwind_info ui;
		unw_cursor_t _cursor;
		uint64_t _ips[];
	};

	struct maps *maps = thread__maps(thread);
	void *addr_space = maps__addr_space(maps);
	struct arch_unwind_info *ui;
	int ret;

	if (addr_space == NULL)
		return NULL;

	ui = zalloc(sizeof(*ui) + sizeof(ui->_ips[0]) * max_stack);
	if (!ui)
		return NULL;

	ui->ui.machine = maps__machine(maps);
	ui->ui.thread = thread;
	ui->ui.sample = sample;
	ui->ui.cursor = &ui->_cursor;
	ui->ui.ips = &ui->_ips[0];
	ui->ui.ips[0] = first_ip;
	ui->ui.cur_ip = 1;
	ui->ui.max_ips = max_stack;
	ui->ui.unw_word_t_size = sizeof(unw_word_t);
	ui->ui.e_machine = EM_ARM;
	ui->ui.best_effort = best_effort;

	ret = unw_init_remote(&ui->_cursor, addr_space, &ui->ui);
	if (ret) {
		if (!best_effort)
			pr_err("libunwind: %s\n", unw_strerror(ret));
		free(ui);
		return NULL;
	}

	return &ui->ui;
#else
	return NULL;
#endif
}

int __libunwind_arch__unwind_step_arm(struct unwind_info *ui __maybe_unused)
{
#ifdef HAVE_LIBUNWIND_ARM_SUPPORT
	int ret;

	if (ui->cur_ip >= ui->max_ips)
		return 0;

	ret = unw_step(ui->cursor);
	if (ret > 0) {
		uint64_t ip;

		unw_get_reg(ui->cursor, UNW_REG_IP, &ip);

		if (unw_is_signal_frame(ui->cursor) <= 0) {
			/*
			 * Decrement the IP for any non-activation frames. This
			 * is required to properly find the srcline for caller
			 * frames.  See also the documentation for
			 * dwfl_frame_pc(), which this code tries to replicate.
			 */
			--ip;
		}
		ui->ips[ui->cur_ip++] = ip;
	}
	return ret;
#else
	return -EINVAL;
#endif
}
