// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause
/*
 * Copyright 2013 Freescale Semiconductor, Inc.
 *
 * 64-bit and little-endian target only until we need to support a different
 * arch that needs this.
 */

#include <elf.h>
#include <errno.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "compiler.h"

#ifndef EM_AARCH64
#define EM_AARCH64		183
#endif

#ifndef R_AARCH64_RELATIVE
#define R_AARCH64_RELATIVE	1027
#endif

#ifndef EM_MICROBLAZE
#define EM_MICROBLAZE		189
#endif

#ifndef R_MICROBLAZE_NONE
#define R_MICROBLAZE_NONE	0
#endif

#ifndef R_MICROBLAZE_32
#define R_MICROBLAZE_32		1
#endif

#ifndef R_MICROBLAZE_REL
#define R_MICROBLAZE_REL	16
#endif

#ifndef R_MICROBLAZE_GLOB_DAT
#define R_MICROBLAZE_GLOB_DAT	18
#endif

static int ei_class;
static int ei_data;

static uint64_t rela_start, rela_end, text_base, dyn_start;

static const bool debug_en;

static void debug(const char *fmt, ...)
{
	va_list args;

	if (debug_en) {
		va_start(args, fmt);
		vprintf(fmt, args);
		va_end(args);
	}
}

static uint16_t elf16_to_cpu(uint16_t data)
{
	if (ei_data == ELFDATA2LSB)
		return le16_to_cpu(data);

	return be16_to_cpu(data);
}

static uint32_t elf32_to_cpu(uint32_t data)
{
	if (ei_data == ELFDATA2LSB)
		return le32_to_cpu(data);

	return be32_to_cpu(data);
}

static bool supported_rela(Elf64_Rela *rela)
{
	uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */
	uint32_t type = rela->r_info & mask;

	switch (type) {
	case R_AARCH64_RELATIVE:
		return true;
	default:
		fprintf(stderr, "warning: unsupported relocation type %"
				PRIu32 " at %" PRIx64 "\n",
			type, rela->r_offset);

		return false;
	}
}

static int decode_elf64(FILE *felf, char **argv)
{
	size_t size;
	Elf64_Ehdr header;
	uint64_t section_header_base, section_header_size;
	uint64_t sh_addr, sh_offset, sh_size;
	Elf64_Half sh_index, sh_num;
	Elf64_Shdr *sh_table; /* Elf symbol table */
	int ret, i, machine;
	char *sh_str;

	debug("64bit version\n");

	/* Make sure we are at start */
	rewind(felf);

	size = fread(&header, 1, sizeof(header), felf);
	if (size != sizeof(header)) {
		fclose(felf);
		return 25;
	}

	machine = le16_to_cpu(header.e_machine);
	debug("Machine\t%d\n", machine);

	if (machine != EM_AARCH64) {
		fprintf(stderr, "%s: Not supported machine type\n", argv[0]);
		return 30;
	}

	text_base = le64_to_cpu(header.e_entry);
	section_header_base = le64_to_cpu(header.e_shoff);
	section_header_size = le16_to_cpu(header.e_shentsize) *
			      le16_to_cpu(header.e_shnum);

	sh_table = malloc(section_header_size);
	if (!sh_table) {
		fprintf(stderr, "%s: Cannot allocate space for section header\n",
			argv[0]);
		fclose(felf);
		return 26;
	}

	ret = fseek(felf, section_header_base, SEEK_SET);
	if (ret) {
		fprintf(stderr, "%s: Can't set pointer to section header: %x/%lx\n",
			argv[0], ret, section_header_base);
		free(sh_table);
		fclose(felf);
		return 26;
	}

	size = fread(sh_table, 1, section_header_size, felf);
	if (size != section_header_size) {
		fprintf(stderr, "%s: Can't read section header: %lx/%lx\n",
			argv[0], size, section_header_size);
		free(sh_table);
		fclose(felf);
		return 27;
	}

	sh_index = le16_to_cpu(header.e_shstrndx);
	sh_size = le64_to_cpu(sh_table[sh_index].sh_size);
	debug("e_shstrndx %x, sh_size %lx\n", sh_index, sh_size);

	sh_str = malloc(sh_size);
	if (!sh_str) {
		fprintf(stderr, "malloc failed\n");
		free(sh_table);
		fclose(felf);
		return 28;
	}

	/*
	 * Specifies the byte offset from the beginning of the file
	 * to the first byte in the section.
	 */
	sh_offset = le64_to_cpu(sh_table[sh_index].sh_offset);
	sh_num = le16_to_cpu(header.e_shnum);

	ret = fseek(felf, sh_offset, SEEK_SET);
	if (ret) {
		fprintf(stderr, "Setting up sh_offset failed\n");
		free(sh_str);
		free(sh_table);
		fclose(felf);
		return 29;
	}

	size = fread(sh_str, 1, sh_size, felf);
	if (size != sh_size) {
		fprintf(stderr, "%s: Can't read section: %lx/%lx\n",
			argv[0], size, sh_size);
		free(sh_str);
		free(sh_table);
		fclose(felf);
		return 30;
	}

	for (i = 0; i < sh_num; i++) {
		char *sh_name = sh_str + le32_to_cpu(sh_table[i].sh_name);

		debug("%s\n", sh_name);

		sh_addr = le64_to_cpu(sh_table[i].sh_addr);
		sh_offset = le64_to_cpu(sh_table[i].sh_offset);
		sh_size = le64_to_cpu(sh_table[i].sh_size);

		if (!strcmp(".rela.dyn", sh_name)) {
			debug("Found section\t\".rela_dyn\"\n");
			debug(" at addr\t0x%08x\n", sh_addr);
			debug(" at offset\t0x%08x\n", sh_offset);
			debug(" of size\t0x%08x\n", sh_size);
			rela_start = sh_addr;
			rela_end = rela_start + sh_size;
			break;
		}
	}

	/* Clean up */
	free(sh_str);
	free(sh_table);
	fclose(felf);

	debug("text_base\t0x%08lx\n", text_base);
	debug("rela_start\t0x%08lx\n", rela_start);
	debug("rela_end\t0x%08lx\n", rela_end);

	if (!rela_start)
		return 1;

	return 0;
}

static int decode_elf32(FILE *felf, char **argv)
{
	size_t size;
	Elf32_Ehdr header;
	uint64_t section_header_base, section_header_size;
	uint32_t sh_addr, sh_offset, sh_size;
	Elf32_Half sh_index, sh_num;
	Elf32_Shdr *sh_table; /* Elf symbol table */
	int ret, i, machine;
	char *sh_str;

	debug("32bit version\n");

	/* Make sure we are at start */
	rewind(felf);

	size = fread(&header, 1, sizeof(header), felf);
	if (size != sizeof(header)) {
		fclose(felf);
		return 25;
	}

	machine = elf16_to_cpu(header.e_machine);
	debug("Machine %d\n", machine);

	if (machine != EM_MICROBLAZE) {
		fprintf(stderr, "%s: Not supported machine type\n", argv[0]);
		return 30;
	}

	text_base = elf32_to_cpu(header.e_entry);
	section_header_base = elf32_to_cpu(header.e_shoff);
	section_header_size = elf16_to_cpu(header.e_shentsize) *
			      elf16_to_cpu(header.e_shnum);

	sh_table = malloc(section_header_size);
	if (!sh_table) {
		fprintf(stderr, "%s: Cannot allocate space for section header\n",
			argv[0]);
		fclose(felf);
		return 26;
	}

	ret = fseek(felf, section_header_base, SEEK_SET);
	if (ret) {
		fprintf(stderr, "%s: Can't set pointer to section header: %x/%lx\n",
			argv[0], ret, section_header_base);
		free(sh_table);
		fclose(felf);
		return 26;
	}

	size = fread(sh_table, 1, section_header_size, felf);
	if (size != section_header_size) {
		fprintf(stderr, "%s: Can't read section header: %lx/%lx\n",
			argv[0], size, section_header_size);
		free(sh_table);
		fclose(felf);
		return 27;
	}

	sh_index = elf16_to_cpu(header.e_shstrndx);
	sh_size = elf32_to_cpu(sh_table[sh_index].sh_size);
	debug("e_shstrndx %x, sh_size %lx\n", sh_index, sh_size);

	sh_str = malloc(sh_size);
	if (!sh_str) {
		fprintf(stderr, "malloc failed\n");
		free(sh_table);
		fclose(felf);
		return 28;
	}

	/*
	 * Specifies the byte offset from the beginning of the file
	 * to the first byte in the section.
	 */
	sh_offset = elf32_to_cpu(sh_table[sh_index].sh_offset);
	sh_num = elf16_to_cpu(header.e_shnum);

	ret = fseek(felf, sh_offset, SEEK_SET);
	if (ret) {
		fprintf(stderr, "Setting up sh_offset failed\n");
		free(sh_str);
		free(sh_table);
		fclose(felf);
		return 29;
	}

	size = fread(sh_str, 1, sh_size, felf);
	if (size != sh_size) {
		fprintf(stderr, "%s: Can't read section: %lx/%x\n",
			argv[0], size, sh_size);
		free(sh_str);
		free(sh_table);
		fclose(felf);
		return 30;
	}

	for (i = 0; i < sh_num; i++) {
		char *sh_name = sh_str + elf32_to_cpu(sh_table[i].sh_name);

		debug("%s\n", sh_name);

		sh_addr = elf32_to_cpu(sh_table[i].sh_addr);
		sh_offset = elf32_to_cpu(sh_table[i].sh_offset);
		sh_size = elf32_to_cpu(sh_table[i].sh_size);

		if (!strcmp(".rela.dyn", sh_name)) {
			debug("Found section\t\".rela_dyn\"\n");
			debug(" at addr\t0x%08x\n", sh_addr);
			debug(" at offset\t0x%08x\n", sh_offset);
			debug(" of size\t0x%08x\n", sh_size);
			rela_start = sh_addr;
			rela_end = rela_start + sh_size;
		}
		if (!strcmp(".dynsym", sh_name)) {
			debug("Found section\t\".dynsym\"\n");
			debug(" at addr\t0x%08x\n", sh_addr);
			debug(" at offset\t0x%08x\n", sh_offset);
			debug(" of size\t0x%08x\n", sh_size);
			dyn_start = sh_addr;
		}
	}

	/* Clean up */
	free(sh_str);
	free(sh_table);
	fclose(felf);

	debug("text_base\t0x%08lx\n", text_base);
	debug("rela_start\t0x%08lx\n", rela_start);
	debug("rela_end\t0x%08lx\n", rela_end);
	debug("dyn_start\t0x%08lx\n", dyn_start);

	if (!rela_start)
		return 1;

	return 0;
}

static int decode_elf(char **argv)
{
	FILE *felf;
	size_t size;
	unsigned char e_ident[EI_NIDENT];

	felf = fopen(argv[2], "r+b");
	if (!felf) {
		fprintf(stderr, "%s: Cannot open %s: %s\n",
			argv[0], argv[5], strerror(errno));
		return 2;
	}

	size = fread(e_ident, 1, EI_NIDENT, felf);
	if (size != EI_NIDENT) {
		fclose(felf);
		return 25;
	}

	/* Check if this is really ELF file */
	if (e_ident[0] != 0x7f &&
	    e_ident[1] != 'E' &&
	    e_ident[2] != 'L' &&
	    e_ident[3] != 'F') {
		fclose(felf);
		return 1;
	}

	ei_class = e_ident[4];
	debug("EI_CLASS(1=32bit, 2=64bit) %d\n", ei_class);

	ei_data = e_ident[5];
	debug("EI_DATA(1=little endian, 2=big endian) %d\n", ei_data);

	if (ei_class == 2)
		return decode_elf64(felf, argv);

	return decode_elf32(felf, argv);
}

static int rela_elf64(char **argv, FILE *f)
{
	int i, num;

	if ((rela_end - rela_start) % sizeof(Elf64_Rela)) {
		fprintf(stderr, "%s: rela size isn't a multiple of Elf64_Rela\n", argv[0]);
		return 3;
	}

	num = (rela_end - rela_start) / sizeof(Elf64_Rela);

	for (i = 0; i < num; i++) {
		Elf64_Rela rela, swrela;
		uint64_t pos = rela_start + sizeof(Elf64_Rela) * i;
		uint64_t addr;

		if (fseek(f, pos, SEEK_SET) < 0) {
			fprintf(stderr, "%s: %s: seek to %" PRIx64
					" failed: %s\n",
				argv[0], argv[1], pos, strerror(errno));
		}

		if (fread(&rela, sizeof(rela), 1, f) != 1) {
			fprintf(stderr, "%s: %s: read rela failed at %"
					PRIx64 "\n",
				argv[0], argv[1], pos);
			return 4;
		}

		swrela.r_offset = le64_to_cpu(rela.r_offset);
		swrela.r_info = le64_to_cpu(rela.r_info);
		swrela.r_addend = le64_to_cpu(rela.r_addend);

		if (!supported_rela(&swrela))
			continue;

		debug("Rela %" PRIx64 " %" PRIu64 " %" PRIx64 "\n",
		      swrela.r_offset, swrela.r_info, swrela.r_addend);

		if (swrela.r_offset < text_base) {
			fprintf(stderr, "%s: %s: bad rela at %" PRIx64 "\n",
				argv[0], argv[1], pos);
			return 4;
		}

		addr = swrela.r_offset - text_base;

		if (fseek(f, addr, SEEK_SET) < 0) {
			fprintf(stderr, "%s: %s: seek to %"
					PRIx64 " failed: %s\n",
				argv[0], argv[1], addr, strerror(errno));
		}

		if (fwrite(&rela.r_addend, sizeof(rela.r_addend), 1, f) != 1) {
			fprintf(stderr, "%s: %s: write failed at %" PRIx64 "\n",
				argv[0], argv[1], addr);
			return 4;
		}
	}

	return 0;
}

static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
{
	uint32_t mask = 0xffULL; /* would be different on 32-bit */
	*type = rela->r_info & mask;

	debug("Type:\t");

	switch (*type) {
	case R_MICROBLAZE_32:
		debug("R_MICROBLAZE_32\n");
		return true;
	case R_MICROBLAZE_GLOB_DAT:
		debug("R_MICROBLAZE_GLOB_DAT\n");
		return true;
	case R_MICROBLAZE_NONE:
		debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
		return false;
	case R_MICROBLAZE_REL:
		debug("R_MICROBLAZE_REL\n");
		return true;
	default:
		fprintf(stderr, "warning: unsupported relocation type %"
			PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);

		return false;
	}
}

static int rela_elf32(char **argv, FILE *f)
{
	int i, num, index;
	uint32_t value, type;

	if ((rela_end - rela_start) % sizeof(Elf32_Rela)) {
		fprintf(stderr, "%s: rela size isn't a multiple of Elf32_Rela\n", argv[0]);
		return 3;
	}

	num = (rela_end - rela_start) / sizeof(Elf32_Rela);

	debug("Number of entries: %u\n", num);

	for (i = 0; i < num; i++) {
		Elf32_Rela rela, swrela;
		Elf32_Sym symbols;
		uint32_t pos = rela_start + sizeof(Elf32_Rela) * i;
		uint32_t addr, pos_dyn;

		debug("\nPossition:\t%d/0x%x\n", i, pos);

		if (fseek(f, pos, SEEK_SET) < 0) {
			fprintf(stderr, "%s: %s: seek to %" PRIx32
					" failed: %s\n",
				argv[0], argv[1], pos, strerror(errno));
		}

		if (fread(&rela, sizeof(rela), 1, f) != 1) {
			fprintf(stderr, "%s: %s: read rela failed at %"
					PRIx32 "\n",
				argv[0], argv[1], pos);
			return 4;
		}

		debug("Rela:\toffset:\t%" PRIx32 " r_info:\t%"
		      PRIu32 " r_addend:\t%" PRIx32 "\n",
		      rela.r_offset, rela.r_info, rela.r_addend);

		swrela.r_offset = elf32_to_cpu(rela.r_offset);
		swrela.r_info = elf32_to_cpu(rela.r_info);
		swrela.r_addend = elf32_to_cpu(rela.r_addend);

		debug("SWRela:\toffset:\t%" PRIx32 " r_info:\t%"
		      PRIu32 " r_addend:\t%" PRIx32 "\n",
		      swrela.r_offset, swrela.r_info, swrela.r_addend);

		if (!supported_rela32(&swrela, &type))
			continue;

		if (swrela.r_offset < text_base) {
			fprintf(stderr, "%s: %s: bad rela at %" PRIx32 "\n",
				argv[0], argv[1], pos);
			return 4;
		}

		addr = swrela.r_offset - text_base;

		debug("Addr:\t0x%" PRIx32 "\n", addr);

		switch (type) {
		case R_MICROBLAZE_REL:
			if (fseek(f, addr, SEEK_SET) < 0) {
				fprintf(stderr, "%s: %s: seek to %"
					PRIx32 " failed: %s\n",
					argv[0], argv[1], addr, strerror(errno));
				return 5;
			}

			debug("Write addend\n");

			if (fwrite(&rela.r_addend, sizeof(rela.r_addend), 1, f) != 1) {
				fprintf(stderr, "%s: %s: write failed at %" PRIx32 "\n",
					argv[0], argv[1], addr);
				return 4;
			}
			break;
		case R_MICROBLAZE_32:
		case R_MICROBLAZE_GLOB_DAT:
			/* global symbols read it and add reloc offset */
			index = swrela.r_info >> 8;
			pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;

			debug("Index:\t%d\n", index);
			debug("Pos_dyn:\t0x%x\n", pos_dyn);

			if (fseek(f, pos_dyn, SEEK_SET) < 0) {
				fprintf(stderr, "%s: %s: seek to %"
					PRIx32 " failed: %s\n",
					argv[0], argv[1], pos_dyn, strerror(errno));
				return 5;
			}

			if (fread(&symbols, sizeof(symbols), 1, f) != 1) {
				fprintf(stderr, "%s: %s: read symbols failed at %"
						PRIx32 "\n",
					argv[0], argv[1], pos_dyn);
				return 4;
			}

			debug("Symbol description:\n");
			debug(" st_name:\t0x%x\n", symbols.st_name);
			debug(" st_value:\t0x%x\n", symbols.st_value);
			debug(" st_size:\t0x%x\n", symbols.st_size);

			value = swrela.r_addend + symbols.st_value;

			debug("Value:\t0x%x\n", value);

			if (fseek(f, addr, SEEK_SET) < 0) {
				fprintf(stderr, "%s: %s: seek to %"
					PRIx32 " failed: %s\n",
					argv[0], argv[1], addr, strerror(errno));
				return 5;
			}

			if (fwrite(&value, sizeof(rela.r_addend), 1, f) != 1) {
				fprintf(stderr, "%s: %s: write failed at %" PRIx32 "\n",
					argv[0], argv[1], addr);
				return 4;
			}

			break;
		case R_MICROBLAZE_NONE:
			debug("R_MICROBLAZE_NONE - skip\n");
			break;
		default:
			fprintf(stderr, "warning: unsupported relocation type %"
				PRIu32 " at %" PRIx32 "\n",
				type, rela.r_offset);
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	FILE *f;
	int ret;
	uint64_t file_size;

	if (argc != 3) {
		fprintf(stderr, "Statically apply ELF rela relocations\n");
		fprintf(stderr, "Usage: %s <bin file> <u-boot ELF>\n",
			argv[0]);
		return 1;
	}

	ret = decode_elf(argv);
	if (ret) {
		fprintf(stderr, "ELF decoding failed\n");
		return ret;
	}

	if (rela_start > rela_end || rela_start < text_base) {
		fprintf(stderr, "%s: bad rela bounds\n", argv[0]);
		return 3;
	}

	rela_start -= text_base;
	rela_end -= text_base;
	dyn_start -= text_base;

	f = fopen(argv[1], "r+b");
	if (!f) {
		fprintf(stderr, "%s: Cannot open %s: %s\n",
			argv[0], argv[1], strerror(errno));
		return 2;
	}

	fseek(f, 0, SEEK_END);
	file_size = ftell(f);
	rewind(f);

	if (rela_end > file_size) {
		// Most likely compiler inserted some section that didn't get
		// objcopy-ed into the final binary
		rela_end = file_size;
	}

	if (ei_class == 2)
		ret = rela_elf64(argv, f);
	else
		ret = rela_elf32(argv, f);

	if (fclose(f) < 0) {
		fprintf(stderr, "%s: %s: close failed: %s\n",
			argv[0], argv[1], strerror(errno));
		return 4;
	}

	return ret;
}
