/*
 * x86 decoder sanity test - based on test_get_insn.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyright (C) IBM Corporation, 2009
 * Copyright (C) Hitachi, Ltd., 2011
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define unlikely(cond) (cond)
#define ARRAY_SIZE(a)	(sizeof(a)/sizeof(a[0]))

#include <asm/insn.h>
#include <inat.c>
#include <insn.c>

/*
 * Test of instruction analysis against tampering.
 * Feed random binary to instruction decoder and ensure not to
 * access out-of-instruction-buffer.
 */

#define DEFAULT_MAX_ITER	10000
#define INSN_NOP 0x90

static const char	*prog;		/* Program name */
static int		verbose;	/* Verbosity */
static int		x86_64;		/* x86-64 bit mode flag */
static unsigned int	seed;		/* Random seed */
static unsigned long	iter_start;	/* Start of iteration number */
static unsigned long	iter_end = DEFAULT_MAX_ITER;	/* End of iteration number */
static FILE		*input_file;	/* Input file name */

static void usage(const char *err)
{
	if (err)
		fprintf(stderr, "Error: %s\n\n", err);
	fprintf(stderr, "Usage: %s [-y|-n|-v] [-s seed[,no]] [-m max] [-i input]\n", prog);
	fprintf(stderr, "\t-y	64bit mode\n");
	fprintf(stderr, "\t-n	32bit mode\n");
	fprintf(stderr, "\t-v	Verbosity(-vv dumps any decoded result)\n");
	fprintf(stderr, "\t-s	Give a random seed (and iteration number)\n");
	fprintf(stderr, "\t-m	Give a maximum iteration number\n");
	fprintf(stderr, "\t-i	Give an input file with decoded binary\n");
	exit(1);
}

static void dump_field(FILE *fp, const char *name, const char *indent,
		       struct insn_field *field)
{
	fprintf(fp, "%s.%s = {\n", indent, name);
	fprintf(fp, "%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
		indent, field->value, field->bytes[0], field->bytes[1],
		field->bytes[2], field->bytes[3]);
	fprintf(fp, "%s\t.got = %d, .nbytes = %d},\n", indent,
		field->got, field->nbytes);
}

static void dump_insn(FILE *fp, struct insn *insn)
{
	fprintf(fp, "Instruction = {\n");
	dump_field(fp, "prefixes", "\t",	&insn->prefixes);
	dump_field(fp, "rex_prefix", "\t",	&insn->rex_prefix);
	dump_field(fp, "vex_prefix", "\t",	&insn->vex_prefix);
	dump_field(fp, "opcode", "\t",		&insn->opcode);
	dump_field(fp, "modrm", "\t",		&insn->modrm);
	dump_field(fp, "sib", "\t",		&insn->sib);
	dump_field(fp, "displacement", "\t",	&insn->displacement);
	dump_field(fp, "immediate1", "\t",	&insn->immediate1);
	dump_field(fp, "immediate2", "\t",	&insn->immediate2);
	fprintf(fp, "\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
		insn->attr, insn->opnd_bytes, insn->addr_bytes);
	fprintf(fp, "\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
		insn->length, insn->x86_64, insn->kaddr);
}

static void dump_stream(FILE *fp, const char *msg, unsigned long nr_iter,
			unsigned char *insn_buf, struct insn *insn)
{
	int i;

	fprintf(fp, "%s:\n", msg);

	dump_insn(fp, insn);

	fprintf(fp, "You can reproduce this with below command(s);\n");

	/* Input a decoded instruction sequence directly */
	fprintf(fp, " $ echo ");
	for (i = 0; i < MAX_INSN_SIZE; i++)
		fprintf(fp, " %02x", insn_buf[i]);
	fprintf(fp, " | %s -i -\n", prog);

	if (!input_file) {
		fprintf(fp, "Or \n");
		/* Give a seed and iteration number */
		fprintf(fp, " $ %s -s 0x%x,%lu\n", prog, seed, nr_iter);
	}
}

static void init_random_seed(void)
{
	int fd;

	fd = open("/dev/urandom", O_RDONLY);
	if (fd < 0)
		goto fail;

	if (read(fd, &seed, sizeof(seed)) != sizeof(seed))
		goto fail;

	close(fd);
	return;
fail:
	usage("Failed to open /dev/urandom");
}

/* Read given instruction sequence from the input file */
static int read_next_insn(unsigned char *insn_buf)
{
	char buf[256]  = "", *tmp;
	int i;

	tmp = fgets(buf, ARRAY_SIZE(buf), input_file);
	if (tmp == NULL || feof(input_file))
		return 0;

	for (i = 0; i < MAX_INSN_SIZE; i++) {
		insn_buf[i] = (unsigned char)strtoul(tmp, &tmp, 16);
		if (*tmp != ' ')
			break;
	}

	return i;
}

static int generate_insn(unsigned char *insn_buf)
{
	int i;

	if (input_file)
		return read_next_insn(insn_buf);

	/* Fills buffer with random binary up to MAX_INSN_SIZE */
	for (i = 0; i < MAX_INSN_SIZE - 1; i += 2)
		*(unsigned short *)(&insn_buf[i]) = random() & 0xffff;

	while (i < MAX_INSN_SIZE)
		insn_buf[i++] = random() & 0xff;

	return i;
}

static void parse_args(int argc, char **argv)
{
	int c;
	char *tmp = NULL;
	int set_seed = 0;

	prog = argv[0];
	while ((c = getopt(argc, argv, "ynvs:m:i:")) != -1) {
		switch (c) {
		case 'y':
			x86_64 = 1;
			break;
		case 'n':
			x86_64 = 0;
			break;
		case 'v':
			verbose++;
			break;
		case 'i':
			if (strcmp("-", optarg) == 0)
				input_file = stdin;
			else
				input_file = fopen(optarg, "r");
			if (!input_file)
				usage("Failed to open input file");
			break;
		case 's':
			seed = (unsigned int)strtoul(optarg, &tmp, 0);
			if (*tmp == ',') {
				optarg = tmp + 1;
				iter_start = strtoul(optarg, &tmp, 0);
			}
			if (*tmp != '\0' || tmp == optarg)
				usage("Failed to parse seed");
			set_seed = 1;
			break;
		case 'm':
			iter_end = strtoul(optarg, &tmp, 0);
			if (*tmp != '\0' || tmp == optarg)
				usage("Failed to parse max_iter");
			break;
		default:
			usage(NULL);
		}
	}

	/* Check errors */
	if (iter_end < iter_start)
		usage("Max iteration number must be bigger than iter-num");

	if (set_seed && input_file)
		usage("Don't use input file (-i) with random seed (-s)");

	/* Initialize random seed */
	if (!input_file) {
		if (!set_seed)	/* No seed is given */
			init_random_seed();
		srand(seed);
	}
}

int main(int argc, char **argv)
{
	struct insn insn;
	int insns = 0;
	int errors = 0;
	unsigned long i;
	unsigned char insn_buf[MAX_INSN_SIZE * 2];

	parse_args(argc, argv);

	/* Prepare stop bytes with NOPs */
	memset(insn_buf + MAX_INSN_SIZE, INSN_NOP, MAX_INSN_SIZE);

	for (i = 0; i < iter_end; i++) {
		if (generate_insn(insn_buf) <= 0)
			break;

		if (i < iter_start)	/* Skip to given iteration number */
			continue;

		/* Decode an instruction */
		insn_init(&insn, insn_buf, x86_64);
		insn_get_length(&insn);

		if (insn.next_byte <= insn.kaddr ||
		    insn.kaddr + MAX_INSN_SIZE < insn.next_byte) {
			/* Access out-of-range memory */
			dump_stream(stderr, "Error: Found an access violation", i, insn_buf, &insn);
			errors++;
		} else if (verbose && !insn_complete(&insn))
			dump_stream(stdout, "Info: Found an undecodable input", i, insn_buf, &insn);
		else if (verbose >= 2)
			dump_insn(stdout, &insn);
		insns++;
	}

	fprintf(stdout, "%s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", (errors) ? "Failure" : "Success", insns, (input_file) ? "given" : "random", errors, seed);

	return errors ? 1 : 0;
}
