/*
   american fuzzy lop++ - fuzzer header
   ------------------------------------

   Originally written by Michal Zalewski

   Now maintained by by Marc Heuse <mh@mh-sec.de>,
                        Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
                        Andrea Fioraldi <andreafioraldi@gmail.com>

   Copyright 2016, 2017 Google Inc. All rights reserved.
   Copyright 2019 AFLplusplus Project. All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at:

     http://www.apache.org/licenses/LICENSE-2.0

   This is the real deal: the program takes an instrumented binary and
   attempts a variety of basic fuzzing tricks, paying close attention to
   how they affect the execution path.

 */

#ifndef _AFL_FUZZ_H
#define _AFL_FUZZ_H

#define AFL_MAIN
#define MESSAGES_TO_STDOUT

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#define _FILE_OFFSET_BITS 64

#ifdef __ANDROID__
#include "android-ashmem.h"
#endif

#include "config.h"
#include "types.h"
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
#include "sharedmem.h"
#include "forkserver.h"
#include "common.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <dirent.h>
#include <ctype.h>
#include <fcntl.h>
#include <termios.h>
#include <dlfcn.h>
#include <sched.h>

#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/file.h>

#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
    defined(__NetBSD__) || defined(__DragonFly__)
#include <sys/sysctl.h>
#endif                           /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */

/* For systems that have sched_setaffinity; right now just Linux, but one
   can hope... */

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
    defined(__DragonFly__)
#define HAVE_AFFINITY 1
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <sys/param.h>
#if defined(__FreeBSD__)
#include <sys/cpuset.h>
#endif
#include <sys/user.h>
#include <pthread.h>
#include <pthread_np.h>
#define cpu_set_t cpuset_t
#elif defined(__NetBSD__)
#include <pthread.h>
#endif
#endif                                                         /* __linux__ */

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

#ifndef SIMPLE_FILES
#define CASE_PREFIX "id:"
#else
#define CASE_PREFIX "id_"
#endif                                                    /* ^!SIMPLE_FILES */

struct queue_entry {

  u8* fname;                            /* File name for the test case      */
  u32 len;                              /* Input length                     */

  u8 cal_failed,                        /* Calibration failed?              */
      trim_done,                        /* Trimmed?                         */
      was_fuzzed,                       /* historical, but needed for MOpt  */
      passed_det,                       /* Deterministic stages passed?     */
      has_new_cov,                      /* Triggers new coverage?           */
      var_behavior,                     /* Variable behavior?               */
      favored,                          /* Currently favored?               */
      fs_redundant;                     /* Marked as redundant in the fs?   */

  u32 bitmap_size,                      /* Number of bits set in bitmap     */
      fuzz_level,                       /* Number of fuzzing iterations     */
      exec_cksum;                       /* Checksum of the execution trace  */

  u64 exec_us,                          /* Execution time (us)              */
      handicap,                         /* Number of queue cycles behind    */
      n_fuzz,                          /* Number of fuzz, does not overflow */
      depth;                            /* Path depth                       */

  u8* trace_mini;                       /* Trace bytes, if kept             */
  u32 tc_ref;                           /* Trace bytes ref count            */

  struct queue_entry *next,             /* Next element, if any             */
      *next_100;                        /* 100 elements ahead               */

};

struct extra_data {

  u8* data;                             /* Dictionary token data            */
  u32 len;                              /* Dictionary token length          */
  u32 hit_cnt;                          /* Use count in the corpus          */

};

/* Fuzzing stages */

enum {

  /* 00 */ STAGE_FLIP1,
  /* 01 */ STAGE_FLIP2,
  /* 02 */ STAGE_FLIP4,
  /* 03 */ STAGE_FLIP8,
  /* 04 */ STAGE_FLIP16,
  /* 05 */ STAGE_FLIP32,
  /* 06 */ STAGE_ARITH8,
  /* 07 */ STAGE_ARITH16,
  /* 08 */ STAGE_ARITH32,
  /* 09 */ STAGE_INTEREST8,
  /* 10 */ STAGE_INTEREST16,
  /* 11 */ STAGE_INTEREST32,
  /* 12 */ STAGE_EXTRAS_UO,
  /* 13 */ STAGE_EXTRAS_UI,
  /* 14 */ STAGE_EXTRAS_AO,
  /* 15 */ STAGE_HAVOC,
  /* 16 */ STAGE_SPLICE,
  /* 17 */ STAGE_PYTHON,
  /* 18 */ STAGE_RADAMSA,
  /* 19 */ STAGE_CUSTOM_MUTATOR

};

/* Stage value types */

enum {

  /* 00 */ STAGE_VAL_NONE,
  /* 01 */ STAGE_VAL_LE,
  /* 02 */ STAGE_VAL_BE

};

/* Execution status fault codes */

enum {

  /* 00 */ FAULT_NONE,
  /* 01 */ FAULT_TMOUT,
  /* 02 */ FAULT_CRASH,
  /* 03 */ FAULT_ERROR,
  /* 04 */ FAULT_NOINST,
  /* 05 */ FAULT_NOBITS

};

/* MOpt:
   Lots of globals, but mostly for the status UI and other things where it
   really makes no sense to haul them around as function parameters. */
extern u64 limit_time_puppet, orig_hit_cnt_puppet, last_limit_time_start,
    tmp_pilot_time, total_pacemaker_time, total_puppet_find, temp_puppet_find,
    most_time_key, most_time, most_execs_key, most_execs, old_hit_count;

extern s32 SPLICE_CYCLES_puppet, limit_time_sig, key_puppet, key_module;

extern double w_init, w_end, w_now;

extern s32 g_now;
extern s32 g_max;

#define operator_num 16
#define swarm_num 5
#define period_core 500000

extern u64 tmp_core_time;
extern s32 swarm_now;

extern double x_now[swarm_num][operator_num], L_best[swarm_num][operator_num],
    eff_best[swarm_num][operator_num], G_best[operator_num],
    v_now[swarm_num][operator_num], probability_now[swarm_num][operator_num],
    swarm_fitness[swarm_num];

extern u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per
                                                           fuzz stage    */
    stage_finds_puppet_v2[swarm_num][operator_num],
    stage_cycles_puppet_v2[swarm_num][operator_num],
    stage_cycles_puppet_v3[swarm_num][operator_num],
    stage_cycles_puppet[swarm_num][operator_num],
    operator_finds_puppet[operator_num],
    core_operator_finds_puppet[operator_num],
    core_operator_finds_puppet_v2[operator_num],
    core_operator_cycles_puppet[operator_num],
    core_operator_cycles_puppet_v2[operator_num],
    core_operator_cycles_puppet_v3[operator_num];   /* Execs per fuzz stage */

#define RAND_C (rand() % 1000 * 0.001)
#define v_max 1
#define v_min 0.05
#define limit_time_bound 1.1
#define SPLICE_CYCLES_puppet_up 25
#define SPLICE_CYCLES_puppet_low 5
#define STAGE_RANDOMBYTE 12
#define STAGE_DELETEBYTE 13
#define STAGE_Clone75 14
#define STAGE_OverWrite75 15
#define period_pilot 50000

extern double period_pilot_tmp;
extern s32    key_lv;

extern u8 *in_dir,                      /* Input directory with test cases  */
    *out_dir,                           /* Working & output directory       */
    *tmp_dir,                           /* Temporary directory for input    */
    *sync_dir,                          /* Synchronization directory        */
    *sync_id,                           /* Fuzzer ID                        */
    *power_name,                        /* Power schedule name              */
    *use_banner,                        /* Display banner                   */
    *in_bitmap,                         /* Input bitmap                     */
    *file_extension,                    /* File extension                   */
    *orig_cmdline,                      /* Original command line            */
    *doc_path,                          /* Path to documentation dir        */
    *infoexec,                         /* Command to execute on a new crash */
    *out_file;                          /* File to fuzz, if any             */

extern u32 exec_tmout;                  /* Configurable exec timeout (ms)   */
extern u32 hang_tmout;                  /* Timeout used for hang det (ms)   */

extern u64 mem_limit;                   /* Memory cap for child (MB)        */

extern u8 cal_cycles,                   /* Calibration cycles defaults      */
    cal_cycles_long,                    /* Calibration cycles defaults      */
    no_unlink,                          /* do not unlink cur_input          */
    use_stdin,                          /* use stdin for sending data       */
    debug,                              /* Debug mode                       */
    custom_only,                        /* Custom mutator only mode         */
    python_only;                        /* Python-only mode                 */

extern u32 stats_update_freq;           /* Stats update frequency (execs)   */

enum {

  /* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
  /* 01 */ FAST,    /* Exponential schedule             */
  /* 02 */ COE,     /* Cut-Off Exponential schedule     */
  /* 03 */ LIN,     /* Linear schedule                  */
  /* 04 */ QUAD,    /* Quadratic schedule               */
  /* 05 */ EXPLOIT, /* AFL's exploitation-based const.  */

  POWER_SCHEDULES_NUM

};

extern char* power_names[POWER_SCHEDULES_NUM];

extern u8 schedule;                     /* Power schedule (default: EXPLORE)*/
extern u8 havoc_max_mult;

extern u8 use_radamsa;
extern size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32);

extern u8 skip_deterministic,           /* Skip deterministic stages?       */
    force_deterministic,                /* Force deterministic stages?      */
    use_splicing,                       /* Recombine input files?           */
    dumb_mode,                          /* Run in non-instrumented mode?    */
    score_changed,                      /* Scoring for favorites changed?   */
    kill_signal,                        /* Signal that killed the child     */
    resuming_fuzz,                      /* Resuming an older fuzzing job?   */
    timeout_given,                      /* Specific timeout given?          */
    not_on_tty,                         /* stdout is not a tty              */
    term_too_small,                     /* terminal dimensions too small    */
    no_forkserver,                      /* Disable forkserver?              */
    crash_mode,                         /* Crash mode! Yeah!                */
    in_place_resume,                    /* Attempt in-place resume?         */
    auto_changed,                       /* Auto-generated tokens changed?   */
    no_cpu_meter_red,                   /* Feng shui on the status screen   */
    no_arith,                           /* Skip most arithmetic ops         */
    shuffle_queue,                      /* Shuffle input queue?             */
    bitmap_changed,                     /* Time to update bitmap?           */
    qemu_mode,                          /* Running in QEMU mode?            */
    unicorn_mode,                       /* Running in Unicorn mode?         */
    use_wine,                           /* Use WINE with QEMU mode          */
    skip_requested,                     /* Skip request, via SIGUSR1        */
    run_over10m,                        /* Run time over 10 minutes?        */
    persistent_mode,                    /* Running in persistent mode?      */
    deferred_mode,                      /* Deferred forkserver mode?        */
    fixed_seed,                         /* do not reseed                    */
    fast_cal,                           /* Try to calibrate faster?         */
    uses_asan,                          /* Target uses ASAN?                */
    disable_trim;                       /* Never trim in fuzz_one           */

extern s32 out_fd,                      /* Persistent fd for out_file       */
#ifndef HAVE_ARC4RANDOM
    dev_urandom_fd,                     /* Persistent fd for /dev/urandom   */
#endif
    dev_null_fd,                        /* Persistent fd for /dev/null      */
    fsrv_ctl_fd,                        /* Fork server control pipe (write) */
    fsrv_st_fd;                         /* Fork server status pipe (read)   */

extern s32 forksrv_pid,                 /* PID of the fork server           */
    child_pid,                          /* PID of the fuzzed program        */
    out_dir_fd;                         /* FD of the lock file              */

extern u8* trace_bits;                  /* SHM with instrumentation bitmap  */

extern u8 virgin_bits[MAP_SIZE],        /* Regions yet untouched by fuzzing */
    virgin_tmout[MAP_SIZE],             /* Bits we haven't seen in tmouts   */
    virgin_crash[MAP_SIZE];             /* Bits we haven't seen in crashes  */

extern u8 var_bytes[MAP_SIZE];          /* Bytes that appear to be variable */

extern volatile u8 stop_soon,           /* Ctrl-C pressed?                  */
    clear_screen,                       /* Window resized?                  */
    child_timed_out;                    /* Traced process timed out?        */

extern u32 queued_paths,                /* Total number of queued testcases */
    queued_variable,                    /* Testcases with variable behavior */
    queued_at_start,                    /* Total number of initial inputs   */
    queued_discovered,                  /* Items discovered during this run */
    queued_imported,                    /* Items imported via -S            */
    queued_favored,                     /* Paths deemed favorable           */
    queued_with_cov,                    /* Paths with new coverage bytes    */
    pending_not_fuzzed,                 /* Queued but not done yet          */
    pending_favored,                    /* Pending favored paths            */
    cur_skipped_paths,                  /* Abandoned inputs in cur cycle    */
    cur_depth,                          /* Current path depth               */
    max_depth,                          /* Max path depth                   */
    useless_at_start,                   /* Number of useless starting paths */
    var_byte_count,                     /* Bitmap bytes with var behavior   */
    current_entry,                      /* Current queue entry ID           */
    havoc_div;                          /* Cycle count divisor for havoc    */

extern u64 total_crashes,               /* Total number of crashes          */
    unique_crashes,                     /* Crashes with unique signatures   */
    total_tmouts,                       /* Total number of timeouts         */
    unique_tmouts,                      /* Timeouts with unique signatures  */
    unique_hangs,                       /* Hangs with unique signatures     */
    total_execs,                        /* Total execve() calls             */
    slowest_exec_ms,                    /* Slowest testcase non hang in ms  */
    start_time,                         /* Unix start time (ms)             */
    last_path_time,                     /* Time for most recent path (ms)   */
    last_crash_time,                    /* Time for most recent crash (ms)  */
    last_hang_time,                     /* Time for most recent hang (ms)   */
    last_crash_execs,                   /* Exec counter at last crash       */
    queue_cycle,                        /* Queue round counter              */
    cycles_wo_finds,                    /* Cycles without any new paths     */
    trim_execs,                         /* Execs done to trim input files   */
    bytes_trim_in,                      /* Bytes coming into the trimmer    */
    bytes_trim_out,                     /* Bytes coming outa the trimmer    */
    blocks_eff_total,                   /* Blocks subject to effector maps  */
    blocks_eff_select;                  /* Blocks selected as fuzzable      */

extern u32 subseq_tmouts;               /* Number of timeouts in a row      */

extern u8 *stage_name,                  /* Name of the current fuzz stage   */
    *stage_short,                       /* Short stage name                 */
    *syncing_party;                     /* Currently syncing with...        */

extern s32 stage_cur, stage_max;        /* Stage progression                */
extern s32 splicing_with;               /* Splicing with which test case?   */

extern u32 master_id, master_max;       /* Master instance job splitting    */

extern u32 syncing_case;                /* Syncing with case #...           */

extern s32 stage_cur_byte,              /* Byte offset of current stage op  */
    stage_cur_val;                      /* Value used for stage op          */

extern u8 stage_val_type;               /* Value type (STAGE_VAL_*)         */

extern u64 stage_finds[32],             /* Patterns found per fuzz stage    */
    stage_cycles[32];                   /* Execs per fuzz stage             */

#ifndef HAVE_ARC4RANDOM
extern u32 rand_cnt;                    /* Random number counter            */
#endif

extern u32 rand_seed[2];
extern s64 init_seed;

extern u64 total_cal_us,                /* Total calibration time (us)      */
    total_cal_cycles;                   /* Total calibration cycles         */

extern u64 total_bitmap_size,           /* Total bit count for all bitmaps  */
    total_bitmap_entries;               /* Number of bitmaps counted        */

extern s32 cpu_core_count;              /* CPU core count                   */

#ifdef HAVE_AFFINITY

extern s32 cpu_aff;                     /* Selected CPU core                */

#endif                                                     /* HAVE_AFFINITY */

extern FILE* plot_file;                 /* Gnuplot output file              */

extern struct queue_entry *queue,       /* Fuzzing queue (linked list)      */
    *queue_cur,                         /* Current offset within the queue  */
    *queue_top,                         /* Top of the list                  */
    *q_prev100;                         /* Previous 100 marker              */

extern struct queue_entry*
    top_rated[MAP_SIZE];                /* Top entries for bitmap bytes     */

extern struct extra_data* extras;       /* Extra tokens to fuzz with        */
extern u32                extras_cnt;   /* Total number of tokens read      */

extern struct extra_data* a_extras;     /* Automatically selected extras    */
extern u32                a_extras_cnt; /* Total number of tokens available */

u8* (*post_handler)(u8* buf, u32* len);

/* hooks for the custom mutator function */
/**
 * Perform custom mutations on a given input
 * @param data Input data to be mutated
 * @param size Size of input data
 * @param mutated_out Buffer to store the mutated input
 * @param max_size Maximum size of the mutated output. The mutation must not
 * produce data larger than max_size.
 * @param seed Seed used for the mutation. The mutation should produce the same
 * output given the same seed.
 * @return Size of the mutated output.
 */
size_t (*custom_mutator)(u8* data, size_t size, u8* mutated_out,
                         size_t max_size, unsigned int seed);
/**
 * A post-processing function to use right before AFL writes the test case to
 * disk in order to execute the target. If this functionality is not needed,
 * Simply don't define this function.
 * @param data Buffer containing the test case to be executed.
 * @param size Size of the test case.
 * @param new_data Buffer to store the test case after processing
 * @return Size of data after processing.
 */
size_t (*pre_save_handler)(u8* data, size_t size, u8** new_data);

/* Interesting values, as per config.h */

extern s8  interesting_8[INTERESTING_8_LEN];
extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN];
extern s32
    interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN];

/* Python stuff */
#ifdef USE_PYTHON

// because Python sets stuff it should not ...
#ifdef _POSIX_C_SOURCE
#define _SAVE_POSIX_C_SOURCE _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#ifdef _XOPEN_SOURCE
#define _SAVE_XOPEN_SOURCE _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif

#include <Python.h>

#ifdef _SAVE_POSIX_C_SOURCE
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE _SAVE_POSIX_C_SOURCE
#endif
#ifdef _SAVE_XOPEN_SOURCE
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE
#endif

extern PyObject* py_module;

enum {

  /* 00 */ PY_FUNC_INIT,
  /* 01 */ PY_FUNC_FUZZ,
  /* 02 */ PY_FUNC_INIT_TRIM,
  /* 03 */ PY_FUNC_POST_TRIM,
  /* 04 */ PY_FUNC_TRIM,
  PY_FUNC_COUNT

};

extern PyObject* py_functions[PY_FUNC_COUNT];

#endif

/**** Prototypes ****/

/* Python */
#ifdef USE_PYTHON
int  init_py();
void finalize_py();
void fuzz_py(char*, size_t, char*, size_t, char**, size_t*);
u32  init_trim_py(char*, size_t);
u32  post_trim_py(char);
void trim_py(char**, size_t*);
u8   trim_case_python(char**, struct queue_entry*, u8*);
#endif

/* Queue */

void mark_as_det_done(struct queue_entry*);
void mark_as_variable(struct queue_entry*);
void mark_as_redundant(struct queue_entry*, u8);
void add_to_queue(u8*, u32, u8);
void destroy_queue(void);
void update_bitmap_score(struct queue_entry*);
void cull_queue(void);
u32  calculate_score(struct queue_entry*);

/* Bitmap */

void write_bitmap(void);
void read_bitmap(u8*);
u8   has_new_bits(u8*);
u32  count_bits(u8*);
u32  count_bytes(u8*);
u32  count_non_255_bytes(u8*);
#ifdef WORD_SIZE_64
void simplify_trace(u64*);
void classify_counts(u64*);
#else
void simplify_trace(u32*);
void classify_counts(u32*);
#endif
void init_count_class16(void);
void minimize_bits(u8*, u8*);
#ifndef SIMPLE_FILES
u8* describe_op(u8);
#endif
u8 save_if_interesting(char**, void*, u32, u8);

/* Misc */

u8* DI(u64);
u8* DF(double);
u8* DMS(u64);
u8* DTD(u64, u64);

/* Extras */

void load_extras_file(u8*, u32*, u32*, u32);
void load_extras(u8*);
void maybe_add_auto(u8*, u32);
void save_auto(void);
void load_auto(void);
void destroy_extras(void);

/* Stats */

void write_stats_file(double, double, double);
void maybe_update_plot_file(double, double);
void show_stats(void);
void show_init_stats(void);

/* Run */

u8   run_target(char**, u32);
void write_to_testcase(void*, u32);
void write_with_gap(void*, u32, u32, u32);
u8   calibrate_case(char**, struct queue_entry*, u8*, u32, u8);
void sync_fuzzers(char**);
u8   trim_case(char**, struct queue_entry*, u8*);
u8   common_fuzz_stuff(char**, u8*, u32);

/* Fuzz one */

u8   fuzz_one_original(char**);
u8   pilot_fuzzing(char**);
u8   core_fuzzing(char**);
void pso_updating(void);
u8   fuzz_one(char**);

/* Init */

#ifdef HAVE_AFFINITY
void bind_to_free_cpu(void);
#endif
void   setup_post(void);
void   setup_custom_mutator(void);
void   read_testcases(void);
void   perform_dry_run(char**);
void   pivot_inputs(void);
u32    find_start_position(void);
void   find_timeout(void);
double get_runnable_processes(void);
void   nuke_resume_dir(void);
void   maybe_delete_out_dir(void);
void   setup_dirs_fds(void);
void   setup_cmdline_file(char**);
void   setup_stdio_file(void);
void   check_crash_handling(void);
void   check_cpu_governor(void);
void   get_core_count(void);
void   fix_up_sync(void);
void   check_asan_opts(void);
void   check_binary(u8*);
void   fix_up_banner(u8*);
void   check_if_tty(void);
void   setup_signal_handlers(void);
char** get_qemu_argv(u8*, char**, int);
char** get_wine_argv(u8*, char**, int);
void   save_cmdline(u32, char**);

/**** Inline routines ****/

/* Generate a random number (from 0 to limit - 1). This may
   have slight bias. */

static inline u32 UR(u32 limit) {

#ifdef HAVE_ARC4RANDOM
  if (fixed_seed) { return random() % limit; }

  /* The boundary not being necessarily a power of 2,
     we need to ensure the result uniformity. */
  return arc4random_uniform(limit);
#else
  if (!fixed_seed && unlikely(!rand_cnt--)) {

    ck_read(dev_urandom_fd, &rand_seed, sizeof(rand_seed), "/dev/urandom");
    srandom(rand_seed[0]);
    rand_cnt = (RESEED_RNG / 2) + (rand_seed[1] % RESEED_RNG);

  }

  return random() % limit;
#endif

}

static inline u32 get_rand_seed() {

  if (fixed_seed) return (u32)init_seed;
  return rand_seed[0];

}

/* Find first power of two greater or equal to val (assuming val under
   2^63). */

static u64 next_p2(u64 val) {

  u64 ret = 1;
  while (val > ret)
    ret <<= 1;
  return ret;

}

/* Get unix time in milliseconds */

static u64 get_cur_time(void) {

  struct timeval  tv;
  struct timezone tz;

  gettimeofday(&tv, &tz);

  return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);

}

/* Get unix time in microseconds */

static u64 get_cur_time_us(void) {

  struct timeval  tv;
  struct timezone tz;

  gettimeofday(&tv, &tz);

  return (tv.tv_sec * 1000000ULL) + tv.tv_usec;

}

#ifdef _AFL_DOCUMENT_MUTATIONS
extern u8  do_document;
extern u32 document_counter;
#endif

#endif

