aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/afl-fuzz.h129
-rw-r--r--include/afl-prealloc.h5
-rw-r--r--include/alloc-inl.h97
-rw-r--r--include/common.h326
-rw-r--r--include/list.h49
-rw-r--r--include/types.h22
6 files changed, 246 insertions, 382 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 7dddefb0..56135d0e 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -239,8 +239,6 @@ enum {
};
-extern u8 *doc_path; /* gath to documentation dir */
-
/* Python stuff */
#ifdef USE_PYTHON
@@ -290,8 +288,20 @@ typedef struct py_mutator {
PyObject *py_module;
PyObject *py_functions[PY_FUNC_COUNT];
- void *afl_state;
- void *py_data;
+ void * afl_state;
+ void * py_data;
+
+ u8 * fuzz_buf;
+ size_t fuzz_size;
+
+ u8 * pre_save_buf;
+ size_t pre_save_size;
+
+ u8 * trim_buf;
+ size_t trim_size;
+
+ u8 * havoc_buf;
+ size_t havoc_size;
} py_mutator_t;
@@ -472,11 +482,6 @@ typedef struct afl_state {
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 */
@@ -484,9 +489,14 @@ typedef struct afl_state {
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 */
+ blocks_eff_select, /* Blocks selected as fuzzable */
+ 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) */
- u32 subseq_tmouts; /* Number of timeouts in a row */
+ 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 */
@@ -541,7 +551,11 @@ typedef struct afl_state {
struct extra_data *a_extras; /* Automatically selected extras */
u32 a_extras_cnt; /* Total number of tokens available */
- u8 *(*post_handler)(u8 *buf, u32 *len);
+ /* afl_postprocess API */
+ void *(*post_init)(struct afl_state *afl);
+ size_t (*post_handler)(void *data, u8 *buf, u32 len, u8 **out_buf);
+ void *(*post_deinit)(void *data);
+ void *post_data;
/* CmpLog */
@@ -550,9 +564,6 @@ typedef struct afl_state {
/* Custom mutators */
struct custom_mutator *mutator;
-#ifdef USE_PYTHON
- struct custom_mutator *py_mutator;
-#endif
/* cmplog forkserver ids */
s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
@@ -580,6 +591,26 @@ typedef struct afl_state {
u8 clean_trace_custom[MAP_SIZE];
u8 first_trace[MAP_SIZE];
+ /*needed for afl_fuzz_one */
+ // TODO: see which we can reuse
+ u8 * out_buf;
+ size_t out_size;
+
+ u8 * out_scratch_buf;
+ size_t out_scratch_size;
+
+ u8 * eff_buf;
+ size_t eff_size;
+
+ u8 * in_buf;
+ size_t in_size;
+
+ u8 * in_scratch_buf;
+ size_t in_scratch_size;
+
+ u8 * ex_buf;
+ size_t ex_size;
+
} afl_state_t;
/* A global pointer to all instances is needed (for now) for signals to arrive
@@ -591,8 +622,10 @@ struct custom_mutator {
const char *name;
void * dh;
+ u8 * pre_save_buf;
+ size_t pre_save_size;
- void *data; /* custom mutator data ptr */
+ void *data; /* custom mutator data ptr */
/* hooks for the custom mutator function */
@@ -611,16 +644,18 @@ struct custom_mutator {
* (Optional for now. Required in the future)
*
* @param data pointer returned in afl_custom_init for this fuzz case
- * @param[inout] buf Pointer to the input data to be mutated and the mutated
+ * @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. We may reuse *buf if large enough.
+ * *out_buf = NULL is treated as FATAL.
* @param[in] add_buf Buffer containing the additional test case
* @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,
+ 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);
/**
@@ -633,10 +668,10 @@ struct custom_mutator {
* @param[in] data pointer returned in afl_custom_init for this fuzz case
* @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 of storing the test case after
- * processing. External library should allocate memory for out_buf. AFL++
- * will release the memory after saving the test case.
- * @return Size of the output buffer after processing
+ * @param[out] out_buf Pointer to the buffer storing the test case after
+ * processing. 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_pre_save)(void *data, u8 *buf, size_t buf_size,
u8 **out_buf);
@@ -660,9 +695,10 @@ struct custom_mutator {
* @param data pointer returned in afl_custom_init for this fuzz case
* @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
+ * @return The amount of possible iteration steps to trim the input.
+ * Negative on error.
*/
- u32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size);
+ 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
@@ -677,11 +713,11 @@ struct custom_mutator {
*
* @param data pointer returned in afl_custom_init for this fuzz case
* @param[out] out_buf Pointer to the buffer containing the trimmed test case.
- * External library should allocate memory for out_buf. AFL++ will release
- * the memory after saving the test case.
- * @param[out] out_buf_size Pointer to the size of 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
*/
- void (*afl_custom_trim)(void *data, u8 **out_buf, size_t *out_buf_size);
+ size_t (*afl_custom_trim)(void *data, u8 **out_buf);
/**
* This method is called after each trim operation to inform you if your
@@ -693,9 +729,9 @@ struct custom_mutator {
* @param data pointer returned in afl_custom_init for this fuzz case
* @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)
+ * steps returned in init_trim). Negative on error.
*/
- u32 (*afl_custom_post_trim)(void *data, u8 success);
+ s32 (*afl_custom_post_trim)(void *data, u8 success);
/**
* Perform a single custom mutation on a given input.
@@ -703,16 +739,18 @@ struct custom_mutator {
*
* (Optional)
*
- * @param data pointer returned in afl_custom_init for this fuzz case
- * @param[inout] buf Pointer to the input data to be mutated and the mutated
+ * @param[in] data pointer returned in afl_custom_init for this fuzz case
+ * @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.
+ * @return Size of the mutated output (out_size).
*/
- size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf,
- size_t buf_size, size_t max_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
@@ -748,9 +786,8 @@ struct custom_mutator {
* @param filename_orig_queue File name of the original queue entry. This
* argument can be NULL while initializing the fuzzer
*/
- void (*afl_custom_queue_new_entry)(void *data,
- const u8 * filename_new_queue,
- const u8 * filename_orig_queue);
+ void (*afl_custom_queue_new_entry)(void *data, const u8 *filename_new_queue,
+ const u8 *filename_orig_queue);
/**
* Deinitialize the custom mutator.
*
@@ -777,10 +814,10 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
void finalize_py_module(void *);
size_t pre_save_py(void *, u8 *, size_t, u8 **);
-u32 init_trim_py(void *, u8 *, size_t);
-u32 post_trim_py(void *, u8);
-void trim_py(void *, u8 **, size_t *);
-size_t havoc_mutation_py(void *, u8 **, size_t, size_t);
+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 *);
void queue_new_entry_py(void *, const u8 *, const u8 *);
@@ -898,13 +935,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
#ifdef HAVE_ARC4RANDOM
- if (afl->fixed_seed) { return random() % limit; }
+ if (unlikely(afl->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 (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) {
+ 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");
@@ -920,7 +957,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
static inline u32 get_rand_seed(afl_state_t *afl) {
- if (afl->fixed_seed) return (u32)afl->init_seed;
+ if (unlikely(afl->fixed_seed)) return (u32)afl->init_seed;
return afl->rand_seed[0];
}
@@ -928,7 +965,7 @@ static inline u32 get_rand_seed(afl_state_t *afl) {
/* Find first power of two greater or equal to val (assuming val under
2^63). */
-static u64 next_p2(u64 val) {
+static inline u64 next_p2(u64 val) {
u64 ret = 1;
while (val > ret)
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h
index ab86f0d7..66e6aadf 100644
--- a/include/afl-prealloc.h
+++ b/include/afl-prealloc.h
@@ -44,9 +44,8 @@ typedef enum prealloc_status {
/* Adds the entry used for prealloc bookkeeping to this struct */
-#define PREALLOCABLE \
- ; \
- pre_status_t pre_status; /* prealloc status of this instance */
+/* prealloc status of this instance */
+#define PREALLOCABLE pre_status_t pre_status
/* allocate an element of type *el_ptr, to this variable.
Uses (and reuses) the given prealloc_buf before hitting libc's malloc.
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index c8783d96..89889cc5 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -35,6 +35,9 @@
#include "types.h"
#include "debug.h"
+/* Initial size used for ck_maybe_grow */
+#define INITIAL_GROWTH_SIZE (64)
+
// Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators
#ifndef _WANT_ORIGINAL_AFL_ALLOC
@@ -764,5 +767,99 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func,
#endif /* _WANT_ORIGINAL_AFL_ALLOC */
+/* This function calculates the next power of 2 greater or equal its argument.
+ @return The rounded up power of 2 (if no overflow) or 0 on overflow.
+*/
+static inline size_t next_pow2(size_t in) {
+
+ if (in == 0 || in > (size_t)-1)
+ return 0; /* avoid undefined behaviour under-/overflow */
+ size_t out = in - 1;
+ out |= out >> 1;
+ out |= out >> 2;
+ out |= out >> 4;
+ out |= out >> 8;
+ out |= out >> 16;
+ return out + 1;
+
+}
+
+/* This function makes sure *size is > size_needed after call.
+ It will realloc *buf otherwise.
+ *size will grow exponentially as per:
+ https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/
+ Will return NULL and free *buf if size_needed is <1 or realloc failed.
+ @return For convenience, this function returns *buf.
+ */
+static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) {
+
+ /* No need to realloc */
+ if (likely(size_needed && *size >= size_needed)) return *buf;
+
+ /* No initial size was set */
+ if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
+
+ /* grow exponentially */
+ size_t next_size = next_pow2(size_needed);
+
+ /* handle overflow and zero size_needed */
+ if (!next_size) { next_size = size_needed; }
+
+ /* alloc */
+ *buf = realloc(*buf, next_size);
+ *size = *buf ? next_size : 0;
+
+ return *buf;
+
+}
+
+/* This function makes sure *size is > size_needed after call.
+ It will realloc *buf otherwise.
+ *size will grow exponentially as per:
+ https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/
+ Will FATAL if size_needed is <1.
+ @return For convenience, this function returns *buf.
+ */
+static inline void *ck_maybe_grow(void **buf, size_t *size,
+ size_t size_needed) {
+
+ /* Oops. found a bug? */
+ if (unlikely(size_needed < 1)) FATAL("cannot grow to non-positive size");
+
+ /* No need to realloc */
+ if (likely(*size >= size_needed)) return *buf;
+
+ /* No initial size was set */
+ if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
+
+ /* grow exponentially */
+ size_t next_size = next_pow2(size_needed);
+
+ /* handle overflow */
+ if (!next_size) { next_size = size_needed; }
+
+ /* alloc */
+ *buf = ck_realloc(*buf, next_size);
+ *size = next_size;
+
+ return *buf;
+
+}
+
+/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */
+static inline void swap_bufs(void **buf1, size_t *size1, void **buf2,
+ size_t *size2) {
+
+ void * scratch_buf = *buf1;
+ size_t scratch_size = *size1;
+ *buf1 = *buf2;
+ *size1 = *size2;
+ *buf2 = scratch_buf;
+ *size2 = scratch_size;
+
+}
+
+#undef INITIAL_GROWTH_SIZE
+
#endif /* ! _HAVE_ALLOC_INL_H */
diff --git a/include/common.h b/include/common.h
index 97076004..c9436e81 100644
--- a/include/common.h
+++ b/include/common.h
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <sys/time.h>
#include "types.h"
#include "stdbool.h"
@@ -47,349 +48,60 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char * get_afl_env(char *env);
-/* Get unix time in milliseconds */
-
-static u64 get_cur_time(void) {
-
- struct timeval tv;
- struct timezone tz;
-
- gettimeofday(&tv, &tz);
+extern u8 be_quiet;
+extern u8 *doc_path; /* path to documentation dir */
- return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
+/* Get unix time in milliseconds */
-}
+u64 get_cur_time(void);
/* 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;
-
-}
+u64 get_cur_time_us(void);
/* Describe integer. The buf should be
at least 6 bytes to fit all ints we randomly see.
Will return buf for convenience. */
-static u8 *stringify_int(u8 *buf, size_t len, u64 val) {
-
-#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
- do { \
- \
- if (val < (_divisor) * (_limit_mult)) { \
- \
- snprintf(buf, len, _fmt, ((_cast)val) / (_divisor)); \
- return buf; \
- \
- } \
- \
- } while (0)
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1000, 99.95, "%0.01fk", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1000, 1000, "%lluk", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double);
-
- /* 100T+ */
- strncpy(buf, "infty", len);
- buf[len - 1] = '\0';
-
- return buf;
-
-}
+u8 *stringify_int(u8 *buf, size_t len, u64 val);
/* Describe float. Similar as int. */
-static u8 *stringify_float(u8 *buf, size_t len, double val) {
-
- if (val < 99.995) {
-
- snprintf(buf, len, "%0.02f", val);
-
- } else if (val < 999.95) {
-
- snprintf(buf, len, "%0.01f", val);
-
- } else {
-
- stringify_int(buf, len, (u64)val);
-
- }
-
- return buf;
-
-}
+u8 *stringify_float(u8 *buf, size_t len, double val);
/* Describe integer as memory size. */
-static u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) {
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu B", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1024, 1000, "%llu kB", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
-
-#undef CHK_FORMAT
-
- /* 100T+ */
- strncpy(buf, "infty", len - 1);
- buf[len - 1] = '\0';
-
- return buf;
-
-}
+u8 *stringify_mem_size(u8 *buf, size_t len, u64 val);
/* Describe time delta as string.
Returns a pointer to buf for convenience. */
-static u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
-
- u64 delta;
- s32 t_d, t_h, t_m, t_s;
- u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
-
- if (!event_ms) {
-
- snprintf(buf, len, "none seen yet");
-
- } else {
-
- delta = cur_ms - event_ms;
-
- t_d = delta / 1000 / 60 / 60 / 24;
- t_h = (delta / 1000 / 60 / 60) % 24;
- t_m = (delta / 1000 / 60) % 60;
- t_s = (delta / 1000) % 60;
-
- stringify_int(val_buf, sizeof(val_buf), t_d);
- snprintf(buf, len, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m,
- t_s);
-
- }
-
- return buf;
-
-}
-
+u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms);
/* Unsafe Describe integer. The buf sizes are not checked.
This is unsafe but fast.
Will return buf for convenience. */
-static u8 *u_stringify_int(u8 *buf, u64 val) {
-
-#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
- do { \
- \
- if (val < (_divisor) * (_limit_mult)) { \
- \
- sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \
- return buf; \
- \
- } \
- \
- } while (0)
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1000, 99.95, "%0.01fk", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1000, 1000, "%lluk", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1000 * 1000, 9.995, "%0.02fM", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1000 * 1000, 99.95, "%0.01fM", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1000 * 1000, 1000, "%lluM", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000, 9.995, "%0.02fG", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1000LL * 1000 * 1000, 99.95, "%0.01fG", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1000LL * 1000 * 1000, 1000, "%lluG", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, "%0.02fT", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, "%0.01fT", double);
-
- /* 100T+ */
- strcpy(buf, "infty");
-
- return buf;
-
-}
+u8 *u_stringify_int(u8 *buf, u64 val);
/* Unsafe describe float. Similar as unsafe int. */
-static u8 *u_stringify_float(u8 *buf, double val) {
-
- if (val < 99.995) {
-
- sprintf(buf, "%0.02f", val);
-
- } else if (val < 999.95) {
-
- sprintf(buf, "%0.01f", val);
-
- } else {
-
- return u_stringify_int(buf, (u64)val);
-
- }
-
- return buf;
-
-}
+u8 *u_stringify_float(u8 *buf, double val);
/* Unsafe describe integer as memory size. */
-static u8 *u_stringify_mem_size(u8 *buf, u64 val) {
-
- /* 0-9999 */
- CHK_FORMAT(1, 10000, "%llu B", u64);
-
- /* 10.0k - 99.9k */
- CHK_FORMAT(1024, 99.95, "%0.01f kB", double);
-
- /* 100k - 999k */
- CHK_FORMAT(1024, 1000, "%llu kB", u64);
-
- /* 1.00M - 9.99M */
- CHK_FORMAT(1024 * 1024, 9.995, "%0.02f MB", double);
-
- /* 10.0M - 99.9M */
- CHK_FORMAT(1024 * 1024, 99.95, "%0.01f MB", double);
-
- /* 100M - 999M */
- CHK_FORMAT(1024 * 1024, 1000, "%llu MB", u64);
-
- /* 1.00G - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024, 9.995, "%0.02f GB", double);
-
- /* 10.0G - 99.9G */
- CHK_FORMAT(1024LL * 1024 * 1024, 99.95, "%0.01f GB", double);
-
- /* 100G - 999G */
- CHK_FORMAT(1024LL * 1024 * 1024, 1000, "%llu GB", u64);
-
- /* 1.00T - 9.99G */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, "%0.02f TB", double);
-
- /* 10.0T - 99.9T */
- CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, "%0.01f TB", double);
-
-#undef CHK_FORMAT
-
- /* 100T+ */
- strcpy(buf, "infty");
-
- return buf;
-
-}
+u8 *u_stringify_mem_size(u8 *buf, u64 val);
/* Unsafe describe time delta as string.
Returns a pointer to buf for convenience. */
-static u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
-
- u64 delta;
- s32 t_d, t_h, t_m, t_s;
- u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
-
- if (!event_ms) {
-
- sprintf(buf, "none seen yet");
-
- } else {
-
- delta = cur_ms - event_ms;
-
- t_d = delta / 1000 / 60 / 60 / 24;
- t_h = (delta / 1000 / 60 / 60) % 24;
- t_m = (delta / 1000 / 60) % 60;
- t_s = (delta / 1000) % 60;
-
- u_stringify_int(val_buf, t_d);
- sprintf(buf, "%s days, %d hrs, %d min, %d sec", val_buf, t_h, t_m, t_s);
-
- }
-
- return buf;
+u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms);
-}
+/* Wrapper for select() and read(), reading exactly len bytes.
+ Returns the time passed to read.
+ If the wait times out, returns timeout_ms + 1;
+ Returns 0 if an error occurred (fd closed, signal, ...); */
+u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms);
#endif
diff --git a/include/list.h b/include/list.h
index 1190931f..e93b4e8f 100644
--- a/include/list.h
+++ b/include/list.h
@@ -34,8 +34,8 @@
#include "debug.h"
#include "afl-prealloc.h"
-#define LIST_PREALLOC_SIZE \
- (64) /* How many elements to allocate before malloc is needed */
+/* How many elements to allocate before malloc is needed */
+#define LIST_PREALLOC_SIZE (64)
typedef struct list_element {
@@ -56,17 +56,18 @@ typedef struct list {
static inline element_t *get_head(list_t *list) {
- return &list->element_prealloc_buf[0];
+ /* The first element is the head */
+ return list->element_prealloc_buf;
}
-static void list_free_el(list_t *list, element_t *el) {
+static inline void list_free_el(list_t *list, element_t *el) {
PRE_FREE(el, list->element_prealloc_count);
}
-static void list_append(list_t *list, void *el) {
+static inline void list_append(list_t *list, void *el) {
element_t *head = get_head(list);
if (!head->next) {
@@ -97,23 +98,23 @@ static void list_append(list_t *list, void *el) {
A return from this block will return from calling func.
*/
-#define LIST_FOREACH(list, type, block) \
- do { \
- \
- list_t * li = (list); \
- element_t *head = get_head((li)); \
- element_t *el_box = (head)->next; \
- if (!el_box) FATAL("foreach over uninitialized list"); \
- while (el_box != head) { \
- \
- type *el = (type *)((el_box)->data); \
- /* get next so el_box can be unlinked */ \
- element_t *next = el_box->next; \
- {block}; \
- el_box = next; \
- \
- } \
- \
+#define LIST_FOREACH(list, type, block) \
+ do { \
+ \
+ list_t * li = (list); \
+ element_t *head = get_head((li)); \
+ element_t *el_box = (head)->next; \
+ if (!el_box) FATAL("foreach over uninitialized list"); \
+ while (el_box != head) { \
+ \
+ __attribute__((unused)) type *el = (type *)((el_box)->data); \
+ /* get next so el_box can be unlinked */ \
+ element_t *next = el_box->next; \
+ {block}; \
+ el_box = next; \
+ \
+ } \
+ \
} while (0);
/* In foreach: remove the current el from the list */
@@ -143,7 +144,7 @@ static void list_append(list_t *list, void *el) {
/* remove an item from the list */
-static void list_remove(list_t *list, void *remove_me) {
+static inline void list_remove(list_t *list, void *remove_me) {
LIST_FOREACH(list, void, {
@@ -165,7 +166,7 @@ static void list_remove(list_t *list, void *remove_me) {
/* Returns true if el is in list */
-static bool list_contains(list_t *list, void *contains_me) {
+static inline bool list_contains(list_t *list, void *contains_me) {
LIST_FOREACH(list, void, {
diff --git a/include/types.h b/include/types.h
index bd4bd05d..da95cb39 100644
--- a/include/types.h
+++ b/include/types.h
@@ -58,8 +58,22 @@ typedef int32_t s32;
typedef int64_t s64;
#ifndef MIN
-#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a))
-#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
+#define MIN(a, b) \
+ ({ \
+ \
+ __typeof__(a) _a = (a); \
+ __typeof__(b) _b = (b); \
+ _a < _b ? _a : _b; \
+ \
+ })
+#define MAX(a, b) \
+ ({ \
+ \
+ __typeof__(a) _a = (a); \
+ __typeof__(b) _b = (b); \
+ _a > _b ? _a : _b; \
+ \
+ })
#endif /* !MIN */
#define SWAP16(_x) \
@@ -120,9 +134,13 @@ typedef int64_t s64;
#define likely(_x) (_x)
#define unlikely(_x) (_x)
#else
+#ifndef likely
#define likely(_x) __builtin_expect(!!(_x), 1)
+#endif
+#ifndef unlikely
#define unlikely(_x) __builtin_expect(!!(_x), 0)
#endif
+#endif
#endif /* ! _HAVE_TYPES_H */