// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 Andes Technology
 * Chih-Mao Chen <cmchen@andestech.com>
 *
 * Statically process runtime relocations on RISC-V ELF images
 * so that it can be directly executed when loaded at LMA
 * without fixup. Both RV32 and RV64 are supported.
 */

#define CONCAT_IMPL(x, y) x##y
#define CONCAT(x, y) CONCAT_IMPL(x, y)
#define CONCAT3(x, y, z) CONCAT(CONCAT(x, y), z)

#define prelink_bonn    CONCAT3(prelink_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
#define uintnn_t        CONCAT3(uint, PRELINK_INC_BITS, _t)
#define get_offset_bonn CONCAT3(get_offset_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
#define Elf_Ehdr        CONCAT3(Elf, PRELINK_INC_BITS, _Ehdr)
#define Elf_Phdr        CONCAT3(Elf, PRELINK_INC_BITS, _Phdr)
#define Elf_Rela        CONCAT3(Elf, PRELINK_INC_BITS, _Rela)
#define Elf_Sym         CONCAT3(Elf, PRELINK_INC_BITS, _Sym)
#define Elf_Dyn         CONCAT3(Elf, PRELINK_INC_BITS, _Dyn)
#define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
#define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
#define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
#define target16_to_cpu CONCAT(PRELINK_BYTEORDER, 16_to_cpu)
#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu)
#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu)
#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu)

static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
{
	Elf_Phdr *p;

	for (p = phdrs; p < phdrs + phnum; ++p)
		if (targetnn_to_cpu(p->p_vaddr) <= addr && targetnn_to_cpu(p->p_vaddr) + targetnn_to_cpu(p->p_memsz) > addr)
			return data + targetnn_to_cpu(p->p_offset) + (addr - targetnn_to_cpu(p->p_vaddr));

	return NULL;
}

static void prelink_bonn(void *data)
{
	Elf_Ehdr *ehdr = data;
	Elf_Phdr *p;
	Elf_Dyn *dyn;
	Elf_Rela *r;

	if (target16_to_cpu(ehdr->e_machine) != EM_RISCV)
		die("Machine type is not RISC-V");

	Elf_Phdr *phdrs = data + targetnn_to_cpu(ehdr->e_phoff);

	Elf_Dyn *dyns = NULL;
	for (p = phdrs; p < phdrs + target16_to_cpu(ehdr->e_phnum); ++p) {
		if (target32_to_cpu(p->p_type) == PT_DYNAMIC) {
			dyns = data + targetnn_to_cpu(p->p_offset);
			break;
		}
	}

	if (dyns == NULL)
		die("No dynamic section found");

	Elf_Rela *rela_dyn = NULL;
	size_t rela_count = 0;
	Elf_Sym *dynsym = NULL;
	for (dyn = dyns;; ++dyn) {
		if (targetnn_to_cpu(dyn->d_tag) == DT_NULL)
			break;
		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA)
			rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ)
		  rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
		else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB)
			dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));

	}

	if (rela_dyn == NULL)
		die("No .rela.dyn found");

	if (dynsym == NULL)
		die("No .dynsym found");

	for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
		void* buf = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), targetnn_to_cpu(r->r_offset));

		if (buf == NULL)
			continue;

		if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
			*((uintnn_t*) buf) = r->r_addend;
		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
			*((uint32_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
			*((uint64_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
	}
}

#undef prelink_bonn
#undef uintnn_t
#undef get_offset_bonn
#undef Elf_Ehdr
#undef Elf_Phdr
#undef Elf_Rela
#undef Elf_Sym
#undef Elf_Dyn
#undef Elf_Addr
#undef ELF_R_TYPE
#undef ELF_R_SYM
#undef target16_to_cpu
#undef target32_to_cpu
#undef target64_to_cpu
#undef targetnn_to_cpu

#undef CONCAT_IMPL
#undef CONCAT
#undef CONCAT3
