void klee_make_symbolic(void *array, size_t nbytes, const char *name) { static int rand_init = -1; if (rand_init == -1) { if (getenv("KLEE_RANDOM")) { struct timeval tv; gettimeofday(&tv, 0); rand_init = 1; srand(tv.tv_sec ^ tv.tv_usec); } else { rand_init = 0; } } if (rand_init) { if (!strcmp(name,"syscall_a0")) { unsigned long long *v = array; assert(nbytes == 8); *v = rand() % 69; } else { char *c = array; size_t i; for (i=0; i<nbytes; i++) c[i] = rand_byte(); } return; } if (!testData) { char tmp[256]; char *name = getenv("KTEST_FILE"); if (!name) { fprintf(stdout, "KLEE-RUNTIME: KTEST_FILE not set, please enter .ktest path: "); fflush(stdout); name = tmp; if (!fgets(tmp, sizeof tmp, stdin) || !strlen(tmp)) { fprintf(stderr, "KLEE-RUNTIME: cannot replay, no KTEST_FILE or user input\n"); exit(1); } tmp[strlen(tmp)-1] = '\0'; /* kill newline */ } testData = kTest_fromFile(name); if (!testData) { fprintf(stderr, "KLEE-RUNTIME: unable to open .ktest file\n"); exit(1); } } if (testPosition >= testData->numObjects) { fprintf(stderr, "ERROR: out of inputs, using zero\n"); memset(array, 0, nbytes); } else { KTestObject *o = &testData->objects[testPosition++]; memcpy(array, o->bytes, nbytes<o->numBytes ? nbytes : o->numBytes); if (nbytes != o->numBytes) { fprintf(stderr, "ERROR: object sizes differ\n"); if (o->numBytes < nbytes) memset((char*) array + o->numBytes, 0, nbytes - o->numBytes); } } }
int main(int argc, char** argv) { int prg_argc; char ** prg_argv; progname = argv[0]; if (argc < 3) usage(); /* Special case hack for only creating files and not actually executing the * program. */ if (strcmp(argv[1], "--create-files-only") == 0) { if (argc != 3) usage(); char* input_fname = argv[2]; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[1]; klee_init_env(&prg_argc, &prg_argv); replay_create_files(&__exe_fs); return 0; } /* Normal execution path ... */ char* executable = argv[1]; /* Verify the executable exists. */ FILE *f = fopen(executable, "r"); if (!f) { fprintf(stderr, "Error: executable %s not found.\n", executable); exit(1); } fclose(f); int idx = 0; for (idx = 2; idx != argc; ++idx) { char* input_fname = argv[idx]; unsigned i; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } obj_index = 0; prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[1]; klee_init_env(&prg_argc, &prg_argv); if (idx > 2) fprintf(stderr, "\n"); fprintf(stderr, "%s: TEST CASE: %s\n", progname, input_fname); fprintf(stderr, "%s: ARGS: ", progname); for (i=0; i != (unsigned) prg_argc; ++i) { char *s = prg_argv[i]; if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0'; fprintf(stderr, "\"%s\" ", prg_argv[i]); } fprintf(stderr, "\n"); /* Run the test case machinery in a subprocess, eventually this parent process should be a script or something which shells out to the actual execution tool. */ int pid = fork(); if (pid < 0) { perror("fork"); _exit(66); } else if (pid == 0) { /* Create the input files, pipes, etc., and run the process. */ replay_create_files(&__exe_fs); run_monitored(executable, prg_argc, prg_argv); _exit(0); } else { /* Wait for the test case. */ int res, status; do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); if (res < 0) { perror("waitpid"); _exit(66); } } } return 0; }
int main(int argc, char** argv) { int prg_argc; char ** prg_argv; progname = argv[0]; if (argc < 3) usage(); int c, opt_index; while ((c = getopt_long(argc, argv, "f:r:", long_options, &opt_index)) != -1) { switch (c) { case 'f': { /* Special case hack for only creating files and not actually executing * the program. */ if (argc != 3) usage(); char* input_fname = optarg; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[1]; klee_init_env(&prg_argc, &prg_argv); replay_create_files(&__exe_fs); return 0; } case 'r': rootdir = optarg; break; } } /* Normal execution path ... */ char* executable = argv[optind]; /* make sure this process has the CAP_SYS_CHROOT capability. */ if (rootdir) ensure_capsyschroot(progname); /* rootdir should be a prefix of executable's path. */ if (rootdir && strstr(executable, rootdir) != executable) { fprintf(stderr, "Error: chroot: root dir should be a parent dir of executable.\n"); exit(1); } /* Verify the executable exists. */ FILE *f = fopen(executable, "r"); if (!f) { fprintf(stderr, "Error: executable %s not found.\n", executable); exit(1); } fclose(f); int idx = 0; for (idx = optind + 1; idx != argc; ++idx) { char* input_fname = argv[idx]; unsigned i; input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } obj_index = 0; prg_argc = input->numArgs; prg_argv = input->args; prg_argv[0] = argv[optind]; klee_init_env(&prg_argc, &prg_argv); if (idx > 2) fprintf(stderr, "\n"); fprintf(stderr, "%s: TEST CASE: %s\n", progname, input_fname); fprintf(stderr, "%s: ARGS: ", progname); for (i=0; i != (unsigned) prg_argc; ++i) { char *s = prg_argv[i]; if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0'; fprintf(stderr, "\"%s\" ", prg_argv[i]); } fprintf(stderr, "\n"); /* Run the test case machinery in a subprocess, eventually this parent process should be a script or something which shells out to the actual execution tool. */ int pid = fork(); if (pid < 0) { perror("fork"); _exit(66); } else if (pid == 0) { /* Create the input files, pipes, etc., and run the process. */ replay_create_files(&__exe_fs); run_monitored(executable, prg_argc, prg_argv); _exit(0); } else { /* Wait for the test case. */ int res, status; do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); if (res < 0) { perror("waitpid"); _exit(66); } } } return 0; }