27 #include <sys/types.h>
31 #define unlikely(cond) (cond)
32 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
44 #define DEFAULT_MAX_ITER 10000
47 static const char *prog;
50 static unsigned int seed;
51 static unsigned long iter_start;
53 static FILE *input_file;
58 fprintf(stderr,
"Error: %s\n\n", err);
59 fprintf(stderr,
"Usage: %s [-y|-n|-v] [-s seed[,no]] [-m max] [-i input]\n", prog);
60 fprintf(stderr,
"\t-y 64bit mode\n");
61 fprintf(stderr,
"\t-n 32bit mode\n");
62 fprintf(stderr,
"\t-v Verbosity(-vv dumps any decoded result)\n");
63 fprintf(stderr,
"\t-s Give a random seed (and iteration number)\n");
64 fprintf(stderr,
"\t-m Give a maximum iteration number\n");
65 fprintf(stderr,
"\t-i Give an input file with decoded binary\n");
72 fprintf(fp,
"%s.%s = {\n", indent, name);
73 fprintf(fp,
"%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
76 fprintf(fp,
"%s\t.got = %d, .nbytes = %d},\n", indent,
80 static void dump_insn(FILE *
fp,
struct insn *
insn)
82 fprintf(fp,
"Instruction = {\n");
92 fprintf(fp,
"\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
94 fprintf(fp,
"\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
98 static void dump_stream(FILE *
fp,
const char *
msg,
unsigned long nr_iter,
99 unsigned char *insn_buf,
struct insn *
insn)
107 fprintf(fp,
"You can reproduce this with below command(s);\n");
112 fprintf(fp,
" %02x", insn_buf[i]);
113 fprintf(fp,
" | %s -i -\n", prog);
118 fprintf(fp,
" $ %s -s 0x%x,%lu\n", prog, seed, nr_iter);
122 static void init_random_seed(
void)
130 if (
read(fd, &seed,
sizeof(seed)) !=
sizeof(seed))
136 usage(
"Failed to open /dev/urandom");
140 static int read_next_insn(
unsigned char *insn_buf)
146 if (
tmp ==
NULL || feof(input_file))
150 insn_buf[
i] = (
unsigned char)strtoul(
tmp, &
tmp, 16);
158 static int generate_insn(
unsigned char *insn_buf)
163 return read_next_insn(insn_buf);
166 for (i = 0; i < MAX_INSN_SIZE - 1; i += 2)
167 *(
unsigned short *)(&insn_buf[
i]) = random() & 0xffff;
169 while (i < MAX_INSN_SIZE)
170 insn_buf[i++] = random() & 0xff;
175 static void parse_args(
int argc,
char **argv)
182 while ((c = getopt(argc, argv,
"ynvs:m:i:")) != -1) {
194 if (
strcmp(
"-", optarg) == 0)
197 input_file = fopen(optarg,
"r");
199 usage(
"Failed to open input file");
202 seed = (
unsigned int)strtoul(optarg, &tmp, 0);
205 iter_start = strtoul(optarg, &tmp, 0);
207 if (*tmp !=
'\0' || tmp == optarg)
208 usage(
"Failed to parse seed");
212 iter_end = strtoul(optarg, &tmp, 0);
213 if (*tmp !=
'\0' || tmp == optarg)
214 usage(
"Failed to parse max_iter");
222 if (iter_end < iter_start)
223 usage(
"Max iteration number must be bigger than iter-num");
225 if (set_seed && input_file)
226 usage(
"Don't use input file (-i) with random seed (-s)");
236 int main(
int argc,
char **argv)
242 unsigned char insn_buf[MAX_INSN_SIZE * 2];
244 parse_args(argc, argv);
249 for (i = 0; i < iter_end; i++) {
250 if (generate_insn(insn_buf) <= 0)
263 dump_stream(stderr,
"Error: Found an access violation", i, insn_buf, &insn);
265 }
else if (
verbose && !insn_complete(&insn))
266 dump_stream(stdout,
"Info: Found an undecodable input", i, insn_buf, &insn);
268 dump_insn(stdout, &insn);
272 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);
274 return errors ? 1 : 0;