arch/x86/tools/insn_sanity.c

Source file repositories/reference/linux-study-clean/arch/x86/tools/insn_sanity.c

File Facts

System
Linux kernel
Corpus path
arch/x86/tools/insn_sanity.c
Extension
.c
Size
6768 bytes
Lines
266
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

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)
{
	int insns = 0, ret;
	struct insn insn;
	int errors = 0;
	unsigned long i;
	unsigned char insn_buff[MAX_INSN_SIZE * 2];

	parse_args(argc, argv);

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

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

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

		/* Decode an instruction */
		ret = insn_decode(&insn, insn_buff, sizeof(insn_buff),
				  x86_64 ? INSN_MODE_64 : INSN_MODE_32);

		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_buff, &insn);
			errors++;
		} else if (verbose && ret < 0)
			dump_stream(stdout, "Info: Found an undecodable input", i, insn_buff, &insn);
		else if (verbose >= 2)
			dump_insn(stdout, &insn);
		insns++;
	}

	fprintf((errors) ? stderr : stdout,

Annotation

Implementation Notes