// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015 Imagination Technologies
 * Author: Alex Smith <alex.smith@imgtec.com>
 */

/*
 * This tool is used to generate the real VDSO images from the raw image. It
 * first patches up the MIPS ABI flags and GNU attributes sections defined in
 * elf.S to have the correct name and type. It then generates a C source file
 * to be compiled into the kernel containing the VDSO image data and a
 * mips_vdso_image struct for it, including symbol offsets extracted from the
 * image.
 *
 * We need to be passed both a stripped and unstripped VDSO image. The stripped
 * image is compiled into the kernel, but we must also patch up the unstripped
 * image's ABI flags sections so that it can be installed and used for
 * debugging.
 */

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <byteswap.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Define these in case the system elf.h is not new enough to have them. */
#ifndef SHT_GNU_ATTRIBUTES
# define SHT_GNU_ATTRIBUTES	0x6ffffff5
#endif
#ifndef SHT_MIPS_ABIFLAGS
# define SHT_MIPS_ABIFLAGS	0x7000002a
#endif

enum {
	ABI_O32 = (1 << 0),
	ABI_N32 = (1 << 1),
	ABI_N64 = (1 << 2),

	ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64,
};

/* Symbols the kernel requires offsets for. */
static struct {
	const char *name;
	const char *offset_name;
	unsigned int abis;
} vdso_symbols[] = {
	{ "__vdso_sigreturn", "off_sigreturn", ABI_O32 },
	{ "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL },
	{}
};

static const char *program_name;
static const char *vdso_name;
static unsigned char elf_class;
static unsigned int elf_abi;
static bool need_swap;
static FILE *out_file;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define HOST_ORDER		ELFDATA2LSB
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define HOST_ORDER		ELFDATA2MSB
#endif

#define BUILD_SWAP(bits)						\
	static uint##bits##_t swap_uint##bits(uint##bits##_t val)	\
	{								\
		return need_swap ? bswap_##bits(val) : val;		\
	}

BUILD_SWAP(16)
BUILD_SWAP(32)
BUILD_SWAP(64)

#define __FUNC(name, bits) name##bits
#define _FUNC(name, bits) __FUNC(name, bits)
#define FUNC(name) _FUNC(name, ELF_BITS)

#define __ELF(x, bits) Elf##bits##_##x
#define _ELF(x, bits) __ELF(x, bits)
#define ELF(x) _ELF(x, ELF_BITS)

/*
 * Include genvdso.h twice with ELF_BITS defined differently to get functions
 * for both ELF32 and ELF64.
 */

#define ELF_BITS 64
#include "genvdso.h"
#undef ELF_BITS

#define ELF_BITS 32
#include "genvdso.h"
#undef ELF_BITS

static void *map_vdso(const char *path, size_t *_size)
{
	int fd;
	struct stat stat;
	void *addr;
	const Elf32_Ehdr *ehdr;

	fd = open(path, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
			path, strerror(errno));
		return NULL;
	}

	if (fstat(fd, &stat) != 0) {
		fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name,
			path, strerror(errno));
		close(fd);
		return NULL;
	}

	addr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
		    0);
	if (addr == MAP_FAILED) {
		fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name,
			path, strerror(errno));
		close(fd);
		return NULL;
	}

	/* ELF32/64 header formats are the same for the bits we're checking. */
	ehdr = addr;

	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
		fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name,
			path);
		close(fd);
		return NULL;
	}

	elf_class = ehdr->e_ident[EI_CLASS];
	switch (elf_class) {
	case ELFCLASS32:
	case ELFCLASS64:
		break;
	default:
		fprintf(stderr, "%s: '%s' has invalid ELF class\n",
			program_name, path);
		close(fd);
		return NULL;
	}

	switch (ehdr->e_ident[EI_DATA]) {
	case ELFDATA2LSB:
	case ELFDATA2MSB:
		need_swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
		break;
	default:
		fprintf(stderr, "%s: '%s' has invalid ELF data order\n",
			program_name, path);
		close(fd);
		return NULL;
	}

	if (swap_uint16(ehdr->e_machine) != EM_MIPS) {
		fprintf(stderr,
			"%s: '%s' has invalid ELF machine (expected EM_MIPS)\n",
			program_name, path);
		close(fd);
		return NULL;
	} else if (swap_uint16(ehdr->e_type) != ET_DYN) {
		fprintf(stderr,
			"%s: '%s' has invalid ELF type (expected ET_DYN)\n",
			program_name, path);
		close(fd);
		return NULL;
	}

	*_size = stat.st_size;
	close(fd);
	return addr;
}

static bool patch_vdso(const char *path, void *vdso)
{
	if (elf_class == ELFCLASS64)
		return patch_vdso64(path, vdso);
	else
		return patch_vdso32(path, vdso);
}

static bool get_symbols(const char *path, void *vdso)
{
	if (elf_class == ELFCLASS64)
		return get_symbols64(path, vdso);
	else
		return get_symbols32(path, vdso);
}

int main(int argc, char **argv)
{
	const char *dbg_vdso_path, *vdso_path, *out_path;
	void *dbg_vdso, *vdso;
	size_t dbg_vdso_size, vdso_size, i;

	program_name = argv[0];

	if (argc < 4 || argc > 5) {
		fprintf(stderr,
			"Usage: %s <debug VDSO> <stripped VDSO> <output file> [<name>]\n",
			program_name);
		return EXIT_FAILURE;
	}

	dbg_vdso_path = argv[1];
	vdso_path = argv[2];
	out_path = argv[3];
	vdso_name = (argc > 4) ? argv[4] : "";

	dbg_vdso = map_vdso(dbg_vdso_path, &dbg_vdso_size);
	if (!dbg_vdso)
		return EXIT_FAILURE;

	vdso = map_vdso(vdso_path, &vdso_size);
	if (!vdso)
		return EXIT_FAILURE;

	/* Patch both the VDSOs' ABI flags sections. */
	if (!patch_vdso(dbg_vdso_path, dbg_vdso))
		return EXIT_FAILURE;
	if (!patch_vdso(vdso_path, vdso))
		return EXIT_FAILURE;

	if (msync(dbg_vdso, dbg_vdso_size, MS_SYNC) != 0) {
		fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
			dbg_vdso_path, strerror(errno));
		return EXIT_FAILURE;
	} else if (msync(vdso, vdso_size, MS_SYNC) != 0) {
		fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
			vdso_path, strerror(errno));
		return EXIT_FAILURE;
	}

	out_file = fopen(out_path, "w");
	if (!out_file) {
		fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
			out_path, strerror(errno));
		return EXIT_FAILURE;
	}

	fprintf(out_file, "/* Automatically generated - do not edit */\n");
	fprintf(out_file, "#include <linux/linkage.h>\n");
	fprintf(out_file, "#include <linux/mm.h>\n");
	fprintf(out_file, "#include <asm/vdso.h>\n");
	fprintf(out_file, "static int vdso_mremap(\n");
	fprintf(out_file, "	const struct vm_special_mapping *sm,\n");
	fprintf(out_file, "	struct vm_area_struct *new_vma)\n");
	fprintf(out_file, "{\n");
	fprintf(out_file, "	current->mm->context.vdso =\n");
	fprintf(out_file, "	(void *)(new_vma->vm_start);\n");
	fprintf(out_file, "	return 0;\n");
	fprintf(out_file, "}\n");

	/* Write out the stripped VDSO data. */
	fprintf(out_file,
		"static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t",
		vdso_size);
	for (i = 0; i < vdso_size; i++) {
		if (!(i % 10))
			fprintf(out_file, "\n\t");
		fprintf(out_file, "0x%02x, ", ((unsigned char *)vdso)[i]);
	}
	fprintf(out_file, "\n};\n");

	/* Preallocate a page array. */
	fprintf(out_file,
		"static struct page *vdso_pages[PAGE_ALIGN(%zu) / PAGE_SIZE];\n",
		vdso_size);

	fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n",
		(vdso_name[0]) ? "_" : "", vdso_name);
	fprintf(out_file, "\t.data = vdso_data,\n");
	fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size);
	fprintf(out_file, "\t.mapping = {\n");
	fprintf(out_file, "\t\t.name = \"[vdso]\",\n");
	fprintf(out_file, "\t\t.pages = vdso_pages,\n");
	fprintf(out_file, "\t\t.mremap = vdso_mremap,\n");
	fprintf(out_file, "\t},\n");

	/* Calculate and write symbol offsets to <output file> */
	if (!get_symbols(dbg_vdso_path, dbg_vdso)) {
		unlink(out_path);
		fclose(out_file);
		return EXIT_FAILURE;
	}

	fprintf(out_file, "};\n");
	fclose(out_file);

	return EXIT_SUCCESS;
}
