#include "config.h"
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <assert.h>
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
#ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON
#endif
u8 __afl_area_initial[MAP_SIZE];
u8* __afl_area_ptr = __afl_area_initial;
u16 __afl_prev_loc;
static void __afl_map_shm(void) {
char *id_str = getenv(SHM_ENV_VAR);
if (id_str) {
u32 shm_id = atoi(id_str);
__afl_area_ptr = shmat(shm_id, NULL, 0);
if (__afl_area_ptr == (void *)-1) exit(1);
__afl_area_ptr[0] = 1;
}
}
static void __afl_start_forkserver(void) {
static u8 tmp[4];
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
while (1) {
s32 child_pid;
int status;
if (read(FORKSRV_FD, tmp, 4) != 4) exit(1);
child_pid = fork();
if (child_pid < 0) exit(1);
if (!child_pid) {
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
return;
}
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(1);
if (waitpid(child_pid, &status, WUNTRACED) < 0) exit(1);
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1);
}
}
void __afl_manual_init(void) {
static u8 init_done;
if (!init_done) {
__afl_map_shm();
__afl_start_forkserver();
init_done = 1;
}
}
__attribute__((constructor(0))) void __afl_auto_init(void) {
if (getenv("AFL_DEFER_FORKSRV")) return;
__afl_manual_init();
}