1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "klee/Internal/ADT/BOut.h"
// --sym-args 0 1 10 --sym-args 0 2 2 --sym-files 1 8 --sym-stdout
static int getint(char *i) {
if(!i) {
fprintf(stderr, "ran out of arguments!\n");
assert(i);
}
return atoi(i);
}
#define MAX 64
static void push_obj(BOut *b, const char *name, unsigned non_zero_bytes,
unsigned total_bytes) {
BOutObject *o = &b->objects[b->numObjects++];
assert(b->numObjects < MAX);
o->name = strdup(name);
o->numBytes = total_bytes;
o->bytes = (unsigned char *)malloc(o->numBytes);
unsigned i;
for(i = 0; i < non_zero_bytes; i++)
o->bytes[i] = random();
for(i = non_zero_bytes; i < total_bytes; i++)
o->bytes[i] = 0;
}
static void push_range(BOut *b, const char *name, unsigned value) {
BOutObject *o = &b->objects[b->numObjects++];
assert(b->numObjects < MAX);
o->name = strdup(name);
o->numBytes = 4;
o->bytes = (unsigned char *)malloc(o->numBytes);
*(unsigned*)o->bytes = value;
}
int main(int argc, char *argv[]) {
unsigned i, narg;
unsigned sym_stdout = 0;
if (argc < 2) {
fprintf(stderr, "Usage: %s <random-seed> <argument-types>\n", argv[0]);
fprintf(stderr, " If <random-seed> is 0, time(NULL)*getpid() is used as a seed\n");
fprintf(stderr, " <argument-types> are the ones accepted by KLEE: --sym-args, --sym-files etc.\n");
fprintf(stderr, " Ex: %s 100 --sym-args 0 2 2 --sym-files 1 8\n", argv[0]);
exit(1);
}
unsigned seed = atoi(argv[1]);
if (seed)
srandom(seed);
else srandom(time(NULL) * getpid());
BOut b;
b.numArgs = argc;
b.args = argv;
b.symArgvs = 0;
b.symArgvLen = 0;
b.numObjects = 0;
b.objects = (BOutObject *)malloc(MAX * sizeof *b.objects);
for(i = 2; i < (unsigned)argc; i++) {
if(strcmp(argv[i], "--sym-args") == 0) {
unsigned lb = getint(argv[++i]);
unsigned ub = getint(argv[++i]);
unsigned nbytes = getint(argv[++i]);
narg = random() % (ub - lb) + lb;
push_range(&b, "range", narg);
while(narg-- > 0) {
unsigned x = random() % (nbytes + 1);
// A little different than how klee does it but more natural
// for random.
static int total_args;
char arg[1024];
sprintf(arg, "arg%d", total_args++);
push_obj(&b, arg, x, nbytes+1);
}
} else if(strcmp(argv[i], "--sym-stdout") == 0) {
if(!sym_stdout) {
sym_stdout = 1;
push_obj(&b, "stdout", 1024, 1024);
push_obj(&b, "stdout-stat", sizeof(struct stat64),
sizeof(struct stat64));
}
} else if(strcmp(argv[i], "--sym-files") == 0) {
unsigned nfiles = getint(argv[++i]);
unsigned nbytes = getint(argv[++i]);
while(nfiles-- > 0) {
push_obj(&b, "file", nbytes, nbytes);
push_obj(&b, "file-stat", sizeof(struct stat64), sizeof(struct stat64));
}
push_obj(&b, "stdin", nbytes, nbytes);
push_obj(&b, "stdin-stat", sizeof(struct stat64), sizeof(struct stat64));
} else {
fprintf(stderr, "unexpected option <%s>\n", argv[i]);
assert(0);
}
}
if (!bOut_toFile(&b, "file.bout"))
assert(0);
return 0;
}
|