// SPDX-License-Identifier: GPL-2.0-only
#include <byteswap.h>
#include <elf.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#ifdef be32toh
/* If libc provides le{16,32,64}toh() then we'll use them */
#elif BYTE_ORDER == LITTLE_ENDIAN
# define le16toh(x)	(x)
# define le32toh(x)	(x)
# define le64toh(x)	(x)
#elif BYTE_ORDER == BIG_ENDIAN
# define le16toh(x)	bswap_16(x)
# define le32toh(x)	bswap_32(x)
# define le64toh(x)	bswap_64(x)
#endif

/* MIPS opcodes, in bits 31:26 of an instruction */
#define OP_SPECIAL	0x00
#define OP_REGIMM	0x01
#define OP_BEQ		0x04
#define OP_BNE		0x05
#define OP_BLEZ		0x06
#define OP_BGTZ		0x07
#define OP_BEQL		0x14
#define OP_BNEL		0x15
#define OP_BLEZL	0x16
#define OP_BGTZL	0x17
#define OP_LL		0x30
#define OP_LLD		0x34
#define OP_SC		0x38
#define OP_SCD		0x3c

/* Bits 20:16 of OP_REGIMM instructions */
#define REGIMM_BLTZ	0x00
#define REGIMM_BGEZ	0x01
#define REGIMM_BLTZL	0x02
#define REGIMM_BGEZL	0x03
#define REGIMM_BLTZAL	0x10
#define REGIMM_BGEZAL	0x11
#define REGIMM_BLTZALL	0x12
#define REGIMM_BGEZALL	0x13

/* Bits 5:0 of OP_SPECIAL instructions */
#define SPECIAL_SYNC	0x0f

static void usage(FILE *f)
{
	fprintf(f, "Usage: loongson3-llsc-check /path/to/vmlinux\n");
}

static int se16(uint16_t x)
{
	return (int16_t)x;
}

static bool is_ll(uint32_t insn)
{
	switch (insn >> 26) {
	case OP_LL:
	case OP_LLD:
		return true;

	default:
		return false;
	}
}

static bool is_sc(uint32_t insn)
{
	switch (insn >> 26) {
	case OP_SC:
	case OP_SCD:
		return true;

	default:
		return false;
	}
}

static bool is_sync(uint32_t insn)
{
	/* Bits 31:11 should all be zeroes */
	if (insn >> 11)
		return false;

	/* Bits 5:0 specify the SYNC special encoding */
	if ((insn & 0x3f) != SPECIAL_SYNC)
		return false;

	return true;
}

static bool is_branch(uint32_t insn, int *off)
{
	switch (insn >> 26) {
	case OP_BEQ:
	case OP_BEQL:
	case OP_BNE:
	case OP_BNEL:
	case OP_BGTZ:
	case OP_BGTZL:
	case OP_BLEZ:
	case OP_BLEZL:
		*off = se16(insn) + 1;
		return true;

	case OP_REGIMM:
		switch ((insn >> 16) & 0x1f) {
		case REGIMM_BGEZ:
		case REGIMM_BGEZL:
		case REGIMM_BGEZAL:
		case REGIMM_BGEZALL:
		case REGIMM_BLTZ:
		case REGIMM_BLTZL:
		case REGIMM_BLTZAL:
		case REGIMM_BLTZALL:
			*off = se16(insn) + 1;
			return true;

		default:
			return false;
		}

	default:
		return false;
	}
}

static int check_ll(uint64_t pc, uint32_t *code, size_t sz)
{
	ssize_t i, max, sc_pos;
	int off;

	/*
	 * Every LL must be preceded by a sync instruction in order to ensure
	 * that instruction reordering doesn't allow a prior memory access to
	 * execute after the LL & cause erroneous results.
	 */
	if (!is_sync(le32toh(code[-1]))) {
		fprintf(stderr, "%" PRIx64 ": LL not preceded by sync\n", pc);
		return -EINVAL;
	}

	/* Find the matching SC instruction */
	max = sz / 4;
	for (sc_pos = 0; sc_pos < max; sc_pos++) {
		if (is_sc(le32toh(code[sc_pos])))
			break;
	}
	if (sc_pos >= max) {
		fprintf(stderr, "%" PRIx64 ": LL has no matching SC\n", pc);
		return -EINVAL;
	}

	/*
	 * Check branches within the LL/SC loop target sync instructions,
	 * ensuring that speculative execution can't generate memory accesses
	 * due to instructions outside of the loop.
	 */
	for (i = 0; i < sc_pos; i++) {
		if (!is_branch(le32toh(code[i]), &off))
			continue;

		/*
		 * If the branch target is within the LL/SC loop then we don't
		 * need to worry about it.
		 */
		if ((off >= -i) && (off <= sc_pos))
			continue;

		/* If the branch targets a sync instruction we're all good... */
		if (is_sync(le32toh(code[i + off])))
			continue;

		/* ...but if not, we have a problem */
		fprintf(stderr, "%" PRIx64 ": Branch target not a sync\n",
			pc + (i * 4));
		return -EINVAL;
	}

	return 0;
}

static int check_code(uint64_t pc, uint32_t *code, size_t sz)
{
	int err = 0;

	if (sz % 4) {
		fprintf(stderr, "%" PRIx64 ": Section size not a multiple of 4\n",
			pc);
		err = -EINVAL;
		sz -= (sz % 4);
	}

	if (is_ll(le32toh(code[0]))) {
		fprintf(stderr, "%" PRIx64 ": First instruction in section is an LL\n",
			pc);
		err = -EINVAL;
	}

#define advance() (	\
	code++,		\
	pc += 4,	\
	sz -= 4		\
)

	/*
	 * Skip the first instructionm allowing check_ll to look backwards
	 * unconditionally.
	 */
	advance();

	/* Now scan through the code looking for LL instructions */
	for (; sz; advance()) {
		if (is_ll(le32toh(code[0])))
			err |= check_ll(pc, code, sz);
	}

	return err;
}

int main(int argc, char *argv[])
{
	int vmlinux_fd, status, err, i;
	const char *vmlinux_path;
	struct stat st;
	Elf64_Ehdr *eh;
	Elf64_Shdr *sh;
	void *vmlinux;

	status = EXIT_FAILURE;

	if (argc < 2) {
		usage(stderr);
		goto out_ret;
	}

	vmlinux_path = argv[1];
	vmlinux_fd = open(vmlinux_path, O_RDONLY);
	if (vmlinux_fd == -1) {
		perror("Unable to open vmlinux");
		goto out_ret;
	}

	err = fstat(vmlinux_fd, &st);
	if (err) {
		perror("Unable to stat vmlinux");
		goto out_close;
	}

	vmlinux = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, vmlinux_fd, 0);
	if (vmlinux == MAP_FAILED) {
		perror("Unable to mmap vmlinux");
		goto out_close;
	}

	eh = vmlinux;
	if (memcmp(eh->e_ident, ELFMAG, SELFMAG)) {
		fprintf(stderr, "vmlinux is not an ELF?\n");
		goto out_munmap;
	}

	if (eh->e_ident[EI_CLASS] != ELFCLASS64) {
		fprintf(stderr, "vmlinux is not 64b?\n");
		goto out_munmap;
	}

	if (eh->e_ident[EI_DATA] != ELFDATA2LSB) {
		fprintf(stderr, "vmlinux is not little endian?\n");
		goto out_munmap;
	}

	for (i = 0; i < le16toh(eh->e_shnum); i++) {
		sh = vmlinux + le64toh(eh->e_shoff) + (i * le16toh(eh->e_shentsize));

		if (sh->sh_type != SHT_PROGBITS)
			continue;
		if (!(sh->sh_flags & SHF_EXECINSTR))
			continue;

		err = check_code(le64toh(sh->sh_addr),
				 vmlinux + le64toh(sh->sh_offset),
				 le64toh(sh->sh_size));
		if (err)
			goto out_munmap;
	}

	status = EXIT_SUCCESS;
out_munmap:
	munmap(vmlinux, st.st_size);
out_close:
	close(vmlinux_fd);
out_ret:
	fprintf(stdout, "loongson3-llsc-check returns %s\n",
		status ? "failure" : "success");
	return status;
}
