aboutsummaryrefslogtreecommitdiff
path: root/include/afl-fuzz.h
blob: c24f39e27c2760f4a197632913091b565bc404d2 (plain)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
/*
   american fuzzy lop++ - fuzzer header
   ------------------------------------

   Originally written by Michal Zalewski

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

   Copyright 2016, 2017 Google Inc. All rights reserved.
   Copyright 2019-2024 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:

     https://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
#endif
#ifndef _FILE_OFFSET_BITS
  #define _FILE_OFFSET_BITS 64
#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 <netdb.h>
#include <netinet/in.h>

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

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

#if defined(__HAIKU__)
  #include <kernel/OS.h>
  #include <kernel/scheduler.h>
#endif

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

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
    defined(__DragonFly__) || defined(__sun)
  #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>
  #elif defined(__sun)
    #include <sys/types.h>
    #include <kstat.h>
    #include <sys/sysinfo.h>
    #include <sys/pset.h>
    #include <strings.h>
  #endif
#endif                                                         /* __linux__ */

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

#undef LIST_FOREACH                                 /* clashes with FreeBSD */
#include "list.h"
#ifndef SIMPLE_FILES
  #define CASE_PREFIX "id:"
#else
  #define CASE_PREFIX "id_"
#endif                                                    /* ^!SIMPLE_FILES */

#define STAGE_BUF_SIZE (64)  /* usable size for stage name buf in afl_state */

// Little helper to access the ptr to afl->##name_buf - for use in afl_realloc.
#define AFL_BUF_PARAM(name) ((void **)&afl->name##_buf)

#ifdef WORD_SIZE_64
  #define AFL_RAND_RETURN u64
#else
  #define AFL_RAND_RETURN u32
#endif

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];

struct tainted {

  u32             pos;
  u32             len;
  struct tainted *next;
  struct tainted *prev;

};

struct inf_profile {

  u32 inf_skipped_bytes;               /* Inference Stage Profiling         */
  u64 inf_execs_cost, inf_time_cost;

};

/* ToDo: add cmplog profile as well */
struct havoc_profile {

  u32 queued_det_stage,                 /* Det/Havoc Stage Profiling        */
      queued_havoc_stage, total_queued_det, edge_det_stage, edge_havoc_stage,
      total_det_edge;

  u64 det_stage_time, havoc_stage_time, total_det_time;

};

struct skipdet_entry {

  u8  continue_inf, done_eff;
  u32 undet_bits, quick_eff_bytes;

  u8 *skip_eff_map,                     /* we'v finish the eff_map          */
      *done_inf_map;                    /* some bytes are not done yet      */

};

struct skipdet_global {

  u8 use_skip_havoc;

  u32 undet_bits_threshold;

  u64 last_cov_undet;

  u8 *virgin_det_bits;                  /* global fuzzed bits               */

  struct inf_profile *inf_prof;

};

struct queue_entry {

  u8 *fname;                            /* File name for the test case      */
  u32 len;                              /* Input length                     */
  u32 id;                               /* entry number in queue_buf        */

  u8 colorized,                         /* Do not run redqueen stage again  */
      cal_failed;                       /* Calibration failed?              */

  bool 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?   */
      is_ascii,                         /* Is the input just ascii text?    */
      disabled;                         /* Is disabled from fuzz selection  */

  u32 bitmap_size,                      /* Number of bits set in bitmap     */
#ifdef INTROSPECTION
      stats_selected,                   /* stats: how often selected        */
      stats_skipped,                    /* stats: how often skipped         */
      stats_finds,                      /* stats: # of saved finds          */
      stats_crashes,                    /* stats: # of saved crashes        */
      stats_tmouts,                     /* stats: # of saved timeouts       */
#endif
      fuzz_level,                       /* Number of fuzzing iterations     */
      n_fuzz_entry;                     /* offset in n_fuzz                 */

  u64 exec_us,                          /* Execution time (us)              */
      handicap,                         /* Number of queue cycles behind    */
      depth,                            /* Path depth                       */
      exec_cksum,                       /* Checksum of the execution trace  */
      custom,                           /* Marker for custom mutators       */
      stats_mutated;                    /* stats: # of mutations performed  */

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

#ifdef INTROSPECTION
  u32 bitsmap_size;
#endif

  double perf_score,                    /* performance score                */
      weight;

  u8 *testcase_buf;                     /* The testcase buffer, if loaded.  */

  u8             *cmplog_colorinput;    /* the result buf of colorization   */
  struct tainted *taint;                /* Taint information from CmpLog    */

  struct queue_entry *mother;           /* queue entry this based on        */

  struct skipdet_entry *skipdet_e;

};

struct extra_data {

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

};

struct auto_extra_data {

  u8  data[MAX_AUTO_EXTRA];             /* 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_EXTRAS_AI,
  /* 16 */ STAGE_HAVOC,
  /* 17 */ STAGE_SPLICE,
  /* 18 */ STAGE_PYTHON,
  /* 19 */ STAGE_CUSTOM_MUTATOR,
  /* 20 */ STAGE_COLORIZATION,
  /* 21 */ STAGE_ITS,
  /* 22 */ STAGE_INF,
  /* 23 */ STAGE_QUICK,

  STAGE_NUM_MAX

};

/* Stage value types */

enum {

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

};

#define operator_num 19
#define swarm_num 5
#define period_core 500000

#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 STAGE_OverWriteExtra 16
#define STAGE_InsertExtra 17
#define STAGE_Splice 18
#define period_pilot 50000

enum {

  /* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
  /* 01 */ MMOPT,   /* Modified MOPT schedule           */
  /* 02 */ EXPLOIT, /* AFL's exploitation-based const.  */
  /* 03 */ FAST,    /* Exponential schedule             */
  /* 04 */ COE,     /* Cut-Off Exponential schedule     */
  /* 05 */ LIN,     /* Linear schedule                  */
  /* 06 */ QUAD,    /* Quadratic schedule               */
  /* 07 */ RARE,    /* Rare edges                       */
  /* 08 */ SEEK,    /* EXPLORE that ignores timings     */

  POWER_SCHEDULES_NUM

};

/* 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

enum {

  /* 00 */ PY_FUNC_INIT,
  /* 01 */ PY_FUNC_DEINIT,
  /* FROM HERE ON BELOW ALL ARE OPTIONAL */
  /* 02 */ PY_OPTIONAL = 2,
  /* 02 */ PY_FUNC_FUZZ = 2,
  /* 03 */ PY_FUNC_FUZZ_COUNT,
  /* 04 */ PY_FUNC_POST_PROCESS,
  /* 05 */ PY_FUNC_INIT_TRIM,
  /* 06 */ PY_FUNC_POST_TRIM,
  /* 07 */ PY_FUNC_TRIM,
  /* 08 */ PY_FUNC_HAVOC_MUTATION,
  /* 09 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY,
  /* 10 */ PY_FUNC_QUEUE_GET,
  /* 11 */ PY_FUNC_QUEUE_NEW_ENTRY,
  /* 12 */ PY_FUNC_INTROSPECTION,
  /* 13 */ PY_FUNC_DESCRIBE,
  /* 14 */ PY_FUNC_FUZZ_SEND,
  /* 15 */ PY_FUNC_SPLICE_OPTOUT,
  /* 16 */ PY_FUNC_POST_RUN,
  PY_FUNC_COUNT

};

typedef struct py_mutator {

  PyObject *py_module;
  PyObject *py_functions[PY_FUNC_COUNT];
  void     *afl_state;
  void     *py_data;

  u8    *fuzz_buf;
  size_t fuzz_size;

  Py_buffer post_process_buf;

  u8    *trim_buf;
  size_t trim_size;

  u8    *havoc_buf;
  size_t havoc_size;

} py_mutator_t;

#endif

typedef struct MOpt_globals {

  u64  *finds;
  u64  *finds_v2;
  u64  *cycles;
  u64  *cycles_v2;
  u64  *cycles_v3;
  u32   is_pilot_mode;
  u64  *pTime;
  u64   period;
  char *havoc_stagename;
  char *splice_stageformat;
  char *havoc_stagenameshort;
  char *splice_stagenameshort;

} MOpt_globals_t;

extern char *power_names[POWER_SCHEDULES_NUM];

typedef struct afl_env_vars {

  u8 afl_skip_cpufreq, afl_exit_when_done, afl_no_affinity, afl_skip_bin_check,
      afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui,
      afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one,
      afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast,
      afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
      afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
      afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
      afl_no_startup_calibration, afl_no_warn_instability,
      afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
      afl_final_sync, afl_ignore_seed_problems;

  u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
      *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
      *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
      *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
      *afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
      *afl_target_env, *afl_persistent_record, *afl_exit_on_time;

  s32 afl_pizza_mode;

} afl_env_vars_t;

struct afl_pass_stat {

  u8 total;
  u8 faileds;

};

struct foreign_sync {

  u8    *dir;
  time_t mtime;

};

typedef struct afl_state {

  /* Position of this state in the global states list */
  u32 _id;

  afl_forkserver_t fsrv;
  sharedmem_t      shm;
  sharedmem_t     *shm_fuzz;
  afl_env_vars_t   afl_env;

  char **argv;                                            /* argv if needed */

  /* 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. */
  u64 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, force_ui_update,
      prev_run_time;

  MOpt_globals_t mopt_globals_core, mopt_globals_pilot;

  s32 limit_time_puppet, SPLICE_CYCLES_puppet, limit_time_sig, key_puppet,
      key_module;

  double w_init, w_end, w_now;

  s32 g_now;
  s32 g_max;

  u64 tmp_core_time;
  s32 swarm_now;

  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];

  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 */

  double period_pilot_tmp;
  s32    key_lv;

  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            */
      *infoexec;                       /* Command to execute on a new crash */

  u32 hang_tmout,                       /* Timeout used for hang det (ms)   */
      stats_update_freq;                /* Stats update frequency (execs)   */

  u8 havoc_stack_pow2,                  /* HAVOC_STACK_POW2                 */
      no_unlink,                        /* do not unlink cur_input          */
      debug,                            /* Debug mode                       */
      custom_only,                      /* Custom mutator only mode         */
      custom_splice_optout,             /* Custom mutator no splice buffer  */
      is_main_node,                     /* if this is the main node         */
      is_secondary_node,                /* if this is a secondary instance  */
      pizza_is_served,                  /* pizza mode                       */
      input_mode,                       /* target wants text inputs         */
      fuzz_mode,          /* coverage/exploration or crash/exploitation mode */
      schedule,                         /* Power schedule (default: EXPLORE)*/
      havoc_max_mult,                   /* havoc multiplier                 */
      skip_deterministic,               /* Skip deterministic stages?       */
      use_splicing,                     /* Recombine input files?           */
      non_instrumented_mode,            /* Run in non-instrumented mode?    */
      score_changed,                    /* Scoring for favorites changed?   */
      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?         */
      autoresume,                       /* Resume if afl->out_dir exists?   */
      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?           */
      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?         */
      disable_trim,                     /* Never trim in fuzz_one           */
      shmem_testcase_mode,              /* If sharedmem testcases are used  */
      expand_havoc,                /* perform expensive havoc after no find */
      cycle_schedules,                  /* cycle power schedules?           */
      old_seed_selection,               /* use vanilla afl seed selection   */
      reinit_table;                     /* reinit the queue weight table    */

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

  double *alias_probability;            /* alias weighted probabilities     */
  u32    *alias_table;                /* alias weighted random lookup table */
  u32     active_items;                 /* enabled entries in the queue     */

  u8 *var_bytes;                        /* Bytes that appear to be variable */

#define N_FUZZ_SIZE (1 << 21)
  u32 *n_fuzz;

  volatile u8 stop_soon,                /* Ctrl-C pressed?                  */
      clear_screen;                     /* Window resized?                  */

  u32 queued_items,                     /* 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_items,                /* 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    */
      max_det_extras;                   /* deterministic extra count (dicts)*/

  u64 total_crashes,                    /* Total number of crashes          */
      saved_crashes,                    /* Crashes with unique signatures   */
      total_tmouts,                     /* Total number of timeouts         */
      saved_tmouts,                     /* Timeouts with unique signatures  */
      saved_hangs,                      /* Hangs with unique signatures     */
      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      */
      start_time,                       /* Unix start time (ms)             */
      last_sync_time,                   /* Time of last sync                */
      last_sync_cycle,                  /* Cycle no. of the last sync       */
      last_find_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)   */
      longest_find_time,                /* Longest time taken for a find    */
      exit_on_time,                     /* Delay to exit if no new paths    */
      sync_time,                        /* Sync time (ms)                   */
      switch_fuzz_mode;                 /* auto or fixed fuzz mode          */

  u32 slowest_exec_ms,                  /* Slowest testcase non hang in ms  */
      subseq_tmouts;                    /* Number of timeouts in a row      */

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

  u8 stage_name_buf[STAGE_BUF_SIZE];    /* reused stagename buf with len 64 */

  u32 stage_cur, stage_max;             /* Stage progression                */
  s32 splicing_with;                    /* Splicing with which test case?   */
  s64 smallest_favored;                 /* smallest queue id favored        */

  u32 main_node_id, main_node_max;      /*   Main instance job splitting    */

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

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

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

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

  u32 rand_cnt;                         /* Random number counter            */

  /*  unsigned long rand_seed[3]; would also work */
  AFL_RAND_RETURN rand_seed[3];
  s64             init_seed;

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

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

  s32 cpu_core_count,                   /* CPU core count                   */
      cpu_to_bind;                      /* bind to specific CPU             */

#ifdef HAVE_AFFINITY
  s32 cpu_aff;                          /* Selected CPU core                */
#endif                                                     /* HAVE_AFFINITY */

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

  // growing buf
  struct queue_entry **queue_buf;

  struct queue_entry **top_rated;           /* Top entries for bitmap bytes */

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

  struct auto_extra_data
      a_extras[MAX_AUTO_EXTRAS];        /* Automatically selected extras    */
  u32 a_extras_cnt;                     /* Total number of tokens available */

  /* afl_postprocess API - Now supported via custom mutators */

  /* CmpLog */

  char            *cmplog_binary;
  afl_forkserver_t cmplog_fsrv;     /* cmplog has its own little forkserver */

  /* Custom mutators */
  struct custom_mutator *mutator;

  /* cmplog forkserver ids */
  s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
  u32 cmplog_prev_timed_out;
  u32 cmplog_max_filesize;
  u32 cmplog_lvl;
  u32 colorize_success;
  u8  cmplog_enable_arith, cmplog_enable_transform, cmplog_enable_scale,
      cmplog_enable_xtreme_transform, cmplog_random_colorization;

  struct afl_pass_stat *pass_stats;
  struct cmp_map       *orig_cmp_map;

  u8 describe_op_buf_256[256]; /* describe_op will use this to return a string
                                  up to 256 */

  unsigned long long int last_avg_exec_update;
  u32                    last_avg_execs;
  double                 last_avg_execs_saved;

/* foreign sync */
#define FOREIGN_SYNCS_MAX 32U
  u8                  foreign_sync_cnt;
  struct foreign_sync foreign_syncs[FOREIGN_SYNCS_MAX];

#ifdef _AFL_DOCUMENT_MUTATIONS
  u8  do_document;
  u32 document_counter;
#endif

  /* statistics file */
  double last_bitmap_cvg, last_stability, last_eps;
  u64    stats_file_update_freq_msecs;  /* Stats update frequency (msecs)   */

  /* plot file saves from last run */
  u32 plot_prev_qp, plot_prev_pf, plot_prev_pnf, plot_prev_ce, plot_prev_md;
  u64 plot_prev_qc, plot_prev_uc, plot_prev_uh, plot_prev_ed;

  u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_queue_ms,
      stats_last_ms, stats_last_execs;

  /* StatsD */
  u64                statsd_last_send_ms;
  struct sockaddr_in statsd_server;
  int                statsd_sock;
  char              *statsd_tags_flavor;
  char              *statsd_tags_format;
  char              *statsd_metric_format;
  int                statsd_metric_format_type;

  double stats_avg_exec;

  u8 *clean_trace;
  u8 *clean_trace_custom;
  u8 *first_trace;

  /*needed for afl_fuzz_one */
  // TODO: see which we can reuse
  u8 *out_buf;

  u8 *out_scratch_buf;

  u8 *eff_buf;

  u8 *in_buf;

  u8 *in_scratch_buf;

  u8 *ex_buf;

  u8 *testcase_buf, *splicecase_buf;

  u32 custom_mutators_count;

  struct custom_mutator *current_custom_fuzz;

  list_t custom_mutator_list;

  /* this is a fixed buffer of size map_size that can be used by any function if
   * they do not call another function */
  u8 *map_tmp_buf;

  /* queue entries ready for splicing count (len > 4) */
  u32 ready_for_splicing_count;

  /* min/max length for generated fuzzing inputs */
  u32 min_length, max_length;

  /* This is the user specified maximum size to use for the testcase cache */
  u64 q_testcase_max_cache_size;

  /* This is the user specified maximum entries in the testcase cache */
  u32 q_testcase_max_cache_entries;

  /* How much of the testcase cache is used so far */
  u64 q_testcase_cache_size;

  /* highest cache count so far */
  u32 q_testcase_max_cache_count;

  /* How many queue entries currently have cached testcases */
  u32 q_testcase_cache_count;

  /* the smallest id currently known free entry */
  u32 q_testcase_smallest_free;

  /* How often did we evict from the cache (for statistics only) */
  u32 q_testcase_evictions;

  /* Refs to each queue entry with cached testcase (for eviction, if cache_count
   * is too large) */
  struct queue_entry **q_testcase_cache;

  /* Global Profile Data for deterministic/havoc-splice stage */
  struct havoc_profile *havoc_prof;

  struct skipdet_global *skipdet_g;

#ifdef INTROSPECTION
  char  mutation[8072];
  char  m_tmp[4096];
  FILE *introspection_file;
  u32   bitsmap_size;
#endif

} afl_state_t;

struct custom_mutator {

  const char *name;
  char       *name_short;
  void       *dh;
  u8         *post_process_buf;
  u8          stacked_custom_prob, stacked_custom;

  void *data;                                    /* custom mutator data ptr */

  /* hooks for the custom mutator function */

  /**
   * Initialize the custom mutator.
   *
   * @param afl AFL instance.
   * @param seed Seed used for the mutation.
   * @return pointer to internal data or NULL on error
   */
  void *(*afl_custom_init)(afl_state_t *afl, unsigned int seed);

  /**
   * When afl-fuzz was compiled with INTROSPECTION=1 then custom mutators can
   * also give introspection information back with this function.
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @return pointer to a text string (const char*)
   */
  const char *(*afl_custom_introspection)(void *data);

  /**
   * This method is called just before fuzzing a queue entry with the custom
   * mutator, and receives the initial buffer. It should return the number of
   * fuzzes to perform.
   *
   * A value of 0 means no fuzzing of this queue entry.
   *
   * The function is now allowed to change the data.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param buf Buffer containing the test case
   * @param buf_size Size of the test case
   * @return The amount of fuzzes to perform on this queue entry, 0 = skip
   */
  u32 (*afl_custom_fuzz_count)(void *data, const u8 *buf, size_t buf_size);

  /**
   * Opt-out of a splicing input for the fuzz mutator
   *
   * Empty dummy function. It's presence tells afl-fuzz not to pass a
   * splice data pointer and len.
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @noreturn
   */
  void (*afl_custom_splice_optout)(void *data);

  /**
   * Perform custom mutations on a given input
   *
   * (Optional)
   *
   * Getting an add_buf can be skipped by using afl_custom_splice_optout().
   *
   * @param[in] data Pointer returned in afl_custom_init by this custom mutator
   * @param[in] buf Pointer to the input data to be mutated and the mutated
   *     output
   * @param[in] buf_size Size of the input/output data
   * @param[out] out_buf The new buffer, under your memory mgmt.
   * @param[in] add_buf Buffer containing an additional test case (splicing)
   * @param[in] add_buf_size Size of the additional test case
   * @param[in] max_size Maximum size of the mutated output. The mutation must
   * not produce data larger than max_size.
   * @return Size of the mutated output.
   */
  size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf,
                            u8 *add_buf, size_t add_buf_size, size_t max_size);

  /**
   * Describe the current testcase, generated by the last mutation.
   * This will be called, for example, to give the written testcase a name
   * after a crash ocurred. It can help to reproduce crashing mutations.
   *
   * (Optional)
   *
   * @param data pointer returned by afl_customm_init for this custom mutator
   * @paramp[in] max_description_len maximum size avaliable for the description.
   *             A longer return string is legal, but will be truncated.
   * @return A valid ptr to a 0-terminated string.
   *         An empty or NULL return will result in a default description
   */
  const char *(*afl_custom_describe)(void *data, size_t max_description_len);

  /**
   * A post-processing function to use right before AFL writes the test case to
   * disk in order to execute the target.
   *
   * NOTE: Do not do any random changes to the data in this function!
   *
   * PERFORMANCE: If you can modify the data in-place you will have a better
   *              performance. Modify *data and set `*out_buf = data`.
   *
   * (Optional) If this functionality is not needed, simply do not define this
   * function.
   *
   * @param[in] data pointer returned in afl_custom_init by this custom mutator
   * @param[in] buf Buffer containing the test case to be executed
   * @param[in] buf_size Size of the test case
   * @param[out] out_buf Pointer to the buffer storing the test case after
   *     processing. The external library should allocate memory for out_buf.
   *     It can chose to alter buf in-place, if the space is large enough.
   * @return Size of the output buffer.
   */
  size_t (*afl_custom_post_process)(void *data, u8 *buf, size_t buf_size,
                                    u8 **out_buf);

  /**
   * This method is called at the start of each trimming operation and receives
   * the initial buffer. It should return the amount of iteration steps possible
   * on this input (e.g. if your input has n elements and you want to remove
   * them one by one, return n, if you do a binary search, return log(n),
   * and so on...).
   *
   * If your trimming algorithm doesn't allow you to determine the amount of
   * (remaining) steps easily (esp. while running), then you can alternatively
   * return 1 here and always return 0 in post_trim until you are finished and
   * no steps remain. In that case, returning 1 in post_trim will end the
   * trimming routine. The whole current index/max iterations stuff is only used
   * to show progress.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param buf Buffer containing the test case
   * @param buf_size Size of the test case
   * @return The amount of possible iteration steps to trim the input.
   *        Negative on error.
   */
  s32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size);

  /**
   * This method is called for each trimming operation. It doesn't have any
   * arguments because we already have the initial buffer from init_trim and we
   * can memorize the current state in global variables. This can also save
   * reparsing steps for each iteration. It should return the trimmed input
   * buffer, where the returned data must not exceed the initial input data in
   * length. Returning anything that is larger than the original data (passed
   * to init_trim) will result in a fatal abort of AFLFuzz.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param[out] out_buf Pointer to the buffer containing the trimmed test case.
   *             The library can reuse a buffer for each call
   *             and will have to free the buf (for example in deinit)
   * @return the size of the trimmed test case
   */
  size_t (*afl_custom_trim)(void *data, u8 **out_buf);

  /**
   * This method is called after each trim operation to inform you if your
   * trimming step was successful or not (in terms of coverage). If you receive
   * a failure here, you should reset your input to the last known good state.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param success Indicates if the last trim operation was successful.
   * @return The next trim iteration index (from 0 to the maximum amount of
   *     steps returned in init_trim). Negative on error.
   */
  s32 (*afl_custom_post_trim)(void *data, u8 success);

  /**
   * Perform a single custom mutation on a given input.
   * This mutation is stacked with the other muatations in havoc.
   *
   * (Optional)
   *
   * @param[in] data pointer returned in afl_custom_init by this custom mutator
   * @param[in] buf Pointer to the input data to be mutated and the mutated
   *     output
   * @param[in] buf_size Size of input data
   * @param[out] out_buf The new buffer. It's legal to reuse *buf if it's <
   * buf_size.
   * @param[in] max_size Maximum size of the mutated output. The mutation must
   *     not produce data larger than max_size.
   * @return Size of the mutated output (out_size).
   */
  size_t (*afl_custom_havoc_mutation)(void *data, u8 *buf, size_t buf_size,
                                      u8 **out_buf, size_t max_size);

  /**
   * Return the probability (in percentage) that afl_custom_havoc_mutation
   * is called in havoc. By default it is 6 %.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @return The probability (0-100).
   */
  u8 (*afl_custom_havoc_mutation_probability)(void *data);

  /**
   * Determine whether the fuzzer should fuzz the current queue entry or not.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param filename File name of the test case in the queue entry
   * @return Return True(1) if the fuzzer will fuzz the queue entry, and
   *     False(0) otherwise.
   */
  u8 (*afl_custom_queue_get)(void *data, const u8 *filename);

  /**
   * This method can be used if you want to send data to the target yourself,
   * e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
   * that you start the target with afl-fuzz.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param buf Buffer containing the test case
   * @param buf_size Size of the test case
   */
  void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size);

  /**
   * This method can be used if you want to run some code or scripts each time
   * AFL++ executes the target with afl-fuzz.
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   */
  void (*afl_custom_post_run)(void *data);

  /**
   * Allow for additional analysis (e.g. calling a different tool that does a
   * different kind of coverage and saves this for the custom mutator).
   *
   * (Optional)
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   * @param filename_new_queue File name of the new queue entry
   * @param filename_orig_queue File name of the original queue entry. This
   *     argument can be NULL while initializing the fuzzer
   */
  u8 (*afl_custom_queue_new_entry)(void *data, const u8 *filename_new_queue,
                                   const u8 *filename_orig_queue);
  /**
   * Deinitialize the custom mutator.
   *
   * @param data pointer returned in afl_custom_init by this custom mutator
   */
  void (*afl_custom_deinit)(void *data);

};

void afl_state_init(afl_state_t *, uint32_t map_size);
void afl_state_deinit(afl_state_t *);

/* Set stop_soon flag on all childs, kill all childs */
void afl_states_stop(void);
/* Set clear_screen flag on all states */
void afl_states_clear_screen(void);
/* Sets the skip flag on all states */
void afl_states_request_skip(void);

/* Setup shmem for testcase delivery */
void setup_testcase_shmem(afl_state_t *afl);

void read_afl_environment(afl_state_t *, char **);

/**** Prototypes ****/

/* Custom mutators */
void setup_custom_mutators(afl_state_t *);
void destroy_custom_mutators(afl_state_t *);
u8   trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf,
                      struct custom_mutator *mutator);
void run_afl_custom_queue_new_entry(afl_state_t *, struct queue_entry *, u8 *,
                                    u8 *);

/* Python */
#ifdef USE_PYTHON

struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
void                   finalize_py_module(void *);

u32         fuzz_count_py(void *, const u8 *, size_t);
void        fuzz_send_py(void *, const u8 *, size_t);
void        post_run_py(void *);
size_t      post_process_py(void *, u8 *, size_t, u8 **);
s32         init_trim_py(void *, u8 *, size_t);
s32         post_trim_py(void *, u8);
size_t      trim_py(void *, u8 **);
size_t      havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t);
u8          havoc_mutation_probability_py(void *);
u8          queue_get_py(void *, const u8 *);
const char *introspection_py(void *);
u8          queue_new_entry_py(void *, const u8 *, const u8 *);
void        splice_optout(void *);
void        deinit_py(void *);

#endif

/* Queue */

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

/* Bitmap */

void write_bitmap(afl_state_t *);
u32  count_bits(afl_state_t *, u8 *);
u32  count_bytes(afl_state_t *, u8 *);
u32  count_non_255_bytes(afl_state_t *, u8 *);
void simplify_trace(afl_state_t *, u8 *);
#ifdef WORD_SIZE_64
void discover_word(u8 *ret, u64 *current, u64 *virgin);
#else
void discover_word(u8 *ret, u32 *current, u32 *virgin);
#endif
void init_count_class16(void);
void minimize_bits(afl_state_t *, u8 *, u8 *);
#ifndef SIMPLE_FILES
u8 *describe_op(afl_state_t *, u8, size_t);
#endif
u8 save_if_interesting(afl_state_t *, void *, u32, u8);
u8 has_new_bits(afl_state_t *, u8 *);
u8 has_new_bits_unclassified(afl_state_t *, u8 *);
#ifndef AFL_SHOWMAP
void classify_counts(afl_forkserver_t *);
#endif

/* Extras */

void load_extras_file(afl_state_t *, u8 *, u32 *, u32 *, u32);
void load_extras(afl_state_t *, u8 *);
void dedup_extras(afl_state_t *);
void deunicode_extras(afl_state_t *);
void add_extra(afl_state_t *afl, u8 *mem, u32 len);
void maybe_add_auto(afl_state_t *, u8 *, u32);
void save_auto(afl_state_t *);
void load_auto(afl_state_t *);
void destroy_extras(afl_state_t *);

/* Stats */

void load_stats_file(afl_state_t *);
void write_setup_file(afl_state_t *, u32, char **);
void write_stats_file(afl_state_t *, u32, double, double, double);
void maybe_update_plot_file(afl_state_t *, u32, double, double);
void write_queue_stats(afl_state_t *);
void show_stats(afl_state_t *);
void show_stats_normal(afl_state_t *);
void show_stats_pizza(afl_state_t *);
void show_init_stats(afl_state_t *);

/* StatsD */

void statsd_setup_format(afl_state_t *afl);
int  statsd_socket_init(afl_state_t *afl);
int  statsd_send_metric(afl_state_t *afl);
int  statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen);

/* Run */

void sync_fuzzers(afl_state_t *);
u32  write_to_testcase(afl_state_t *, void **, u32, u32);
u8   calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
u8   trim_case(afl_state_t *, struct queue_entry *, u8 *);
u8   common_fuzz_stuff(afl_state_t *, u8 *, u32);
fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);

/* Fuzz one */

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

/* Init */

#ifdef HAVE_AFFINITY
void bind_to_free_cpu(afl_state_t *);
#endif
void   setup_post(afl_state_t *);
void   read_testcases(afl_state_t *, u8 *);
void   perform_dry_run(afl_state_t *);
void   pivot_inputs(afl_state_t *);
u32    find_start_position(afl_state_t *);
void   find_timeout(afl_state_t *);
double get_runnable_processes(void);
void   nuke_resume_dir(afl_state_t *);
int    check_main_node_exists(afl_state_t *);
u32    select_next_queue_entry(afl_state_t *afl);
void   create_alias_table(afl_state_t *afl);
void   setup_dirs_fds(afl_state_t *);
void   setup_cmdline_file(afl_state_t *, char **);
void   setup_stdio_file(afl_state_t *);
void   check_crash_handling(void);
void   check_cpu_governor(afl_state_t *);
void   get_core_count(afl_state_t *);
void   fix_up_sync(afl_state_t *);
void   check_asan_opts(afl_state_t *);
void   check_binary(afl_state_t *, u8 *);
void   check_if_tty(afl_state_t *);
void   save_cmdline(afl_state_t *, u32, char **);
void   read_foreign_testcases(afl_state_t *, int);
void   write_crash_readme(afl_state_t *afl);
u8     check_if_text_buf(u8 *buf, u32 len);
#ifndef AFL_SHOWMAP
void setup_signal_handlers(void);
#endif
char *get_fuzzing_state(afl_state_t *afl);

/* CmpLog */

u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);

/* RedQueen */
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len);

/* our RNG wrapper */
AFL_RAND_RETURN rand_next(afl_state_t *afl);

/* probability between 0.0 and 1.0 */
double rand_next_percent(afl_state_t *afl);

/* SkipDet Functions */

u8 skip_deterministic_stage(afl_state_t *, u8 *, u8 *, u32, u64);
u8 is_det_timeout(u64, u8);

void plot_profile_data(afl_state_t *, struct queue_entry *);

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

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

static inline u32 rand_below(afl_state_t *afl, u32 limit) {

  if (unlikely(limit <= 1)) return 0;

  /* The boundary not being necessarily a power of 2,
     we need to ensure the result uniformity. */
  if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {

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

  }

  /* Modulo is biased - we don't want our fuzzing to be biased so let's do it
   right. See:
   https://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator
   */
  u64 unbiased_rnd;
  do {

    unbiased_rnd = rand_next(afl);

  } while (unlikely(unbiased_rnd >= (UINT64_MAX - (UINT64_MAX % limit))));

  return unbiased_rnd % limit;

}

/* we prefer lower range values here */
/* this is only called with normal havoc, not MOpt, to have an equalizer for
   expand havoc mode */
static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) {

  if (unlikely(limit <= 1)) return 0;

  switch (rand_below(afl, 3)) {

    case 2:
      return (rand_below(afl, limit) % (1 + rand_below(afl, limit - 1))) %
             (1 + rand_below(afl, limit - 1));
      break;
    case 1:
      return rand_below(afl, limit) % (1 + rand_below(afl, limit - 1));
      break;
    case 0:
      return rand_below(afl, limit);
      break;

  }

  return 1;  // cannot be reached

}

static inline s64 rand_get_seed(afl_state_t *afl) {

  if (unlikely(afl->fixed_seed)) { return afl->init_seed; }
  return afl->rand_seed[0];

}

/* initialize randomness with a given seed. Can be called again at any time. */
void rand_set_seed(afl_state_t *afl, s64 init_seed);

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

static inline u64 next_p2(u64 val) {

  u64 ret = 1;
  while (val > ret) {

    ret <<= 1;

  }

  return ret;

}

/* Returns the testcase buf from the file behind this queue entry.
  Increases the refcount. */
u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q);

/* If trimming changes the testcase size we have to reload it */
void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q,
                           u32 old_len);

/* If trimming changes the testcase size we have to replace it  */
void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, u8 *in,
                               u32 len, u32 old_len);

/* Add a new queue entry directly to the cache */

void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, u8 *mem);

#if TESTCASE_CACHE == 1
  #error define of TESTCASE_CACHE must be zero or larger than 1
#endif

#endif