diff options
author | Dominik Maier <domenukk@gmail.com> | 2020-03-09 11:24:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-09 11:24:10 +0100 |
commit | dba3595c0ae26795a78753ea33ff0c3edf9d6328 (patch) | |
tree | 03bcaf132705d6de222ef8d6eff9b5bc2f03ce54 /include/afl-prealloc.h | |
parent | c159b872ef17d4c09238f99ac11021e12975cb3a (diff) | |
download | afl++-dba3595c0ae26795a78753ea33ff0c3edf9d6328.tar.gz |
AFL without globals (#220)
* moved globals to afl, shm and fsrv * moved argv to afl state, less bugs * fixed unicorn docu * lists everywhere * merged custom mutators * fixed leaks in afl-fuzz
Diffstat (limited to 'include/afl-prealloc.h')
-rw-r--r-- | include/afl-prealloc.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h new file mode 100644 index 00000000..712cdec6 --- /dev/null +++ b/include/afl-prealloc.h @@ -0,0 +1,101 @@ +/* If we know we'll reuse small elements often, we'll just preallocate a buffer, then fall back to malloc */ +// TODO: Replace free status check with bitmask+CLZ + +#ifndef AFL_PREALLOC_H +#define AFL_PREALLOC_H + +#include <stdio.h> +#include <stdbool.h> +#include <string.h> + +#include "debug.h" + +typedef enum prealloc_status { + PRE_STATUS_UNUSED = 0,/* free in buf */ + PRE_STATUS_USED, /* used in buf */ + PRE_STATUS_MALLOC /* system malloc */ +} pre_status_t; + + +/* Adds the entry used for prealloc bookkeeping to this struct */ + +#define PREALLOCABLE ;pre_status_t pre_status; /* prealloc status of this instance */ + + +/* allocate an element of type *el_ptr, to this variable. + Uses (and reuses) the given prealloc_buf before hitting libc's malloc. + prealloc_buf must be the pointer to an array with type `type`. + `type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status member). + prealloc_size must be the array size. + prealloc_counter must be a variable initialized with 0 (of any name). + */ + +#define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) do { \ + \ + if ((prealloc_counter) >= (prealloc_size)) { \ + \ + el_ptr = malloc(sizeof(*el_ptr)); \ + el_ptr->pre_status = PRE_STATUS_MALLOC; \ + \ + } else { \ + \ + /* Find one of our preallocated elements */ \ + u32 i; \ + for (i = 0; i < (prealloc_size); i++) { \ + \ + el_ptr = &((prealloc_buf)[i]); \ + if (el_ptr->pre_status == PRE_STATUS_UNUSED) { \ + \ + (prealloc_counter)++; \ + el_ptr->pre_status = PRE_STATUS_USED; \ + break; \ + \ + } \ + } \ + } \ + \ + if(!el_ptr) { \ + FATAL("BUG in list.h -> no element found or allocated!"); \ + } \ +} while(0); + + +/* Take a chosen (free) element from the prealloc_buf directly */ + +#define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) do { \ + if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \ + FATAL("PRE_ALLOC_FORCE element already allocated"); \ + } \ + (el_ptr)->pre_status = PRE_STATUS_USED; \ + (prealloc_counter)++; \ +} while(0); + + +/* free an preallocated element */ + +#define PRE_FREE(el_ptr, prealloc_counter) do { \ + \ + switch ((el_ptr)->pre_status) { \ + \ + case PRE_STATUS_USED: { \ + (el_ptr)->pre_status = PRE_STATUS_UNUSED; \ + (prealloc_counter)--; \ + if ((prealloc_counter) < 0) { \ + FATAL("Inconsistent data in PRE_FREE"); \ + } \ + break; \ + } \ + case PRE_STATUS_MALLOC: { \ + (el_ptr)->pre_status = PRE_STATUS_UNUSED; \ + free((el_ptr)); \ + break; \ + } \ + default: { \ + FATAL("Double Free Detected"); \ + break; \ + } \ + \ + } \ +} while(0); + +#endif |