/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // This file serves as a kind of template, used to separate the code needed // to run the various testing tools (Klee, libfuzz, random fuzzer) // from the code defining the blocks of the code under test. // To use this file: // 1) Include it, // 2) Define the following values: NUM_THREADS, SCHEDULE_POINTS, and // CONTEXT_SWITCHES_BOUND. // 3) Define a function int test_with_schedule(uint8_t* // schedule, size_t len), which should create 'NUM_THREADS' base_frames and call // execute_schedule( // schedule, // len, // frames, // 'NUM_THREADS' base_frames. // NUM_THREADS, // CONTEXT_SWITCHES_BOUND // ); int test_with_schedule(uint8_t* schedule, size_t len); #ifdef KLEE #include uint8_t* make_symbolic_schedule(int schedule_len, int max_id) { uint8_t* schedule = malloc(sizeof(int) * schedule_len); klee_make_symbolic(schedule, sizeof(int) * schedule_len, "schedule"); for (int schedule_idx = 0; schedule_idx < schedule_len; ++schedule_idx) { uint8_t current_id = schedule[schedule_idx]; klee_assume(current_id < max_id); } return schedule; } // Klee entry point. int main(void) { // print_test(); // return 0; uint8_t* schedule = make_symbolic_schedule(SCHEDULE_POINTS, NUM_THREADS); test_with_schedule(schedule, SCHEDULE_POINTS); return 0; } #endif #ifdef RAND_FUZZ static int fuzz_counter = 0; int main(void) { uint8_t schedule[SCHEDULE_POINTS]; while (true) { for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { schedule[idx] = rand() % NUM_THREADS; } printf("schedule %d: ", fuzz_counter); ++fuzz_counter; for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { printf("%hhu ", schedule[idx]); } printf("\n"); test_with_schedule(schedule, SCHEDULE_POINTS); } return 0; } #endif // RAND_FUZZ #ifdef ENUM_FUZZ static int fuzz_counter = 0; int main(void) { uint8_t schedule[SCHEDULE_POINTS]; for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { schedule[idx] = 0; } while (true) { bool all_max = true; for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { if (schedule[idx] != NUM_THREADS - 1) { all_max = false; break; } } if (all_max) { return 0; } printf("schedule %d: ", fuzz_counter); ++fuzz_counter; for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { printf("%hhu ", schedule[idx]); } printf("\n"); test_with_schedule(schedule, SCHEDULE_POINTS); for (int idx = 0; idx < SCHEDULE_POINTS; ++idx) { if (schedule[idx] < NUM_THREADS - 1) { ++schedule[idx]; break; } else { for (int idx2 = idx; idx2 < SCHEDULE_POINTS; ++idx2) { if (schedule[idx2] == NUM_THREADS - 1) { schedule[idx2] = 0; } else { ++schedule[idx2]; break; } } break; } } } return 0; } #endif // ENUM_FUZZ #ifdef FUZZ static int fuzz_counter = 0; int LLVMFuzzerTestOneInput(uint8_t* schedule, size_t size) { if (size > SCHEDULE_POINTS) { return 0; } for (int idx = 0; idx < size; ++idx) { if (schedule[idx] >= NUM_THREADS) { return 0; } } printf("fuzz schedule: %d\n", fuzz_counter); ++fuzz_counter; // printf("schedule size: %zu\n", size); // for (int idx = 0; idx < size; ++idx) { // printf("%hhu ", schedule[idx]); // } // printf("\n"); test_with_schedule(schedule, size); return 0; // Non-zero return values are reserved for future use. } #endif // FUZZ