#include "mymemory.h"
#include "common.h"
#include "context.h"
+#include "model.h"
+
+
+#if USE_MPROTECT_SNAPSHOT
/** PageAlignedAdressUpdate return a page aligned address for the
* address being added as a side effect the numBytes are also changed.
return (void *)((((uintptr_t)addr) + PAGESIZE - 1) & ~(PAGESIZE - 1));
}
-#if USE_MPROTECT_SNAPSHOT
-
/* Each SnapShotRecord lists the firstbackingpage that must be written to
* revert to that snapshot */
struct SnapShotRecord {
static void mprot_snapshot_init(unsigned int numbackingpages,
unsigned int numsnapshots, unsigned int nummemoryregions,
- unsigned int numheappages, VoidFuncPtr entryPoint)
+ unsigned int numheappages)
{
/* Setup a stack for our signal handler.... */
stack_t ss;
pagealignedbase = PageAlignAddressUpward(base_model_snapshot_space);
model_snapshot_space = create_mspace_with_base(pagealignedbase, numheappages * PAGESIZE, 1);
snapshot_add_memory_region(pagealignedbase, numheappages);
+}
- entryPoint();
+static void mprot_startExecution(ucontext_t * context, VoidFuncPtr entryPoint) {
+ /* setup the shared-stack context */
+ create_context(context, fork_snap->mStackBase, model_calloc(STACK_SIZE_DEFAULT, 1), STACK_SIZE_DEFAULT, entryPoint);
}
static void mprot_add_to_snapshot(void *addr, unsigned int numPages)
#else /* !USE_MPROTECT_SNAPSHOT */
-#define SHARED_MEMORY_DEFAULT (100 * ((size_t)1 << 20)) // 100mb for the shared memory
+#define SHARED_MEMORY_DEFAULT (200 * ((size_t)1 << 20)) // 100mb for the shared memory
#define STACK_SIZE_DEFAULT (((size_t)1 << 20) * 20) // 20 mb out of the above 100 mb for my stack
struct fork_snapshotter {
*/
volatile snapshot_id mIDToRollback;
- /**
- * @brief The context for the shared (non-snapshot) stack
- *
- * This context is passed between the various processes which represent
- * various snapshot states. It should be used primarily for the
- * "client-side" code, not the main snapshot loop.
- */
- ucontext_t shared_ctxt;
+
/** @brief Inter-process tracking of the next snapshot ID */
snapshot_id currSnapShotID;
};
static struct fork_snapshotter *fork_snap = NULL;
+ucontext_t shared_ctxt;
/** @statics
* These variables are necessary because the stack is shared region and
getcontext(ctxt);
ctxt->uc_stack.ss_sp = stack;
ctxt->uc_stack.ss_size = stacksize;
+ ctxt->uc_link = NULL;
makecontext(ctxt, func, 0);
}
* process */
static void fork_exit()
{
- /* Intentionally empty */
+ _Exit(EXIT_SUCCESS);
}
static void createSharedMemory()
static void fork_snapshot_init(unsigned int numbackingpages,
unsigned int numsnapshots, unsigned int nummemoryregions,
- unsigned int numheappages, VoidFuncPtr entryPoint)
+ unsigned int numheappages)
{
if (!fork_snap)
createSharedMemory();
- void *base_model_snapshot_space = malloc((numheappages + 1) * PAGESIZE);
- void *pagealignedbase = PageAlignAddressUpward(base_model_snapshot_space);
- model_snapshot_space = create_mspace_with_base(pagealignedbase, numheappages * PAGESIZE, 1);
-
- /* setup an "exiting" context */
- char stack[128];
- create_context(&exit_ctxt, stack, sizeof(stack), fork_exit);
+ model_snapshot_space = create_mspace(numheappages * PAGESIZE, 1);
+}
- /* setup the shared-stack context */
- create_context(&fork_snap->shared_ctxt, fork_snap->mStackBase,
- STACK_SIZE_DEFAULT, entryPoint);
- /* switch to a new entryPoint context, on a new stack */
- model_swapcontext(&private_ctxt, &fork_snap->shared_ctxt);
+volatile int modellock = 0;
+static void fork_loop() {
/* switch back here when takesnapshot is called */
snapshotid = fork_snap->currSnapShotID;
+ if (model->params.nofork) {
+ setcontext(&shared_ctxt);
+ _Exit(EXIT_SUCCESS);
+ }
while (true) {
pid_t forkedID;
fork_snap->currSnapShotID = snapshotid + 1;
+
+ modellock = 1;
forkedID = fork();
+ modellock = 0;
if (0 == forkedID) {
- setcontext(&fork_snap->shared_ctxt);
+ setcontext(&shared_ctxt);
} else {
DEBUG("parent PID: %d, child PID: %d, snapshot ID: %d\n",
getpid(), forkedID, snapshotid);
}
}
- if (fork_snap->mIDToRollback != snapshotid)
- exit(EXIT_SUCCESS);
+ if (fork_snap->mIDToRollback != snapshotid) {
+ char filename[256];
+ snprintf_(filename, sizeof(filename), "C11FuzzerTmp%d", forkedID);
+ unlink(filename);
+
+ _Exit(EXIT_SUCCESS);
+ }
}
}
}
-static snapshot_id fork_take_snapshot()
-{
- model_swapcontext(&fork_snap->shared_ctxt, &private_ctxt);
+static void fork_startExecution(ucontext_t *context, VoidFuncPtr entryPoint) {
+ /* setup an "exiting" context */
+ int exit_stack_size = 256;
+ create_context(&exit_ctxt, snapshot_calloc(exit_stack_size, 1), exit_stack_size, fork_exit);
+
+ /* setup the system context */
+ create_context(context, fork_snap->mStackBase, STACK_SIZE_DEFAULT, entryPoint);
+ /* switch to a new entryPoint context, on a new stack */
+ create_context(&private_ctxt, snapshot_calloc(STACK_SIZE_DEFAULT, 1), STACK_SIZE_DEFAULT, fork_loop);
+}
+
+static snapshot_id fork_take_snapshot() {
+ model_swapcontext(&shared_ctxt, &private_ctxt);
DEBUG("TAKESNAPSHOT RETURN\n");
return snapshotid;
}
{
DEBUG("Rollback\n");
fork_snap->mIDToRollback = theID;
- model_swapcontext(&fork_snap->shared_ctxt, &exit_ctxt);
+ model_swapcontext(model->get_system_context(), &exit_ctxt);
fork_snap->mIDToRollback = -1;
}
*/
void snapshot_system_init(unsigned int numbackingpages,
unsigned int numsnapshots, unsigned int nummemoryregions,
- unsigned int numheappages, VoidFuncPtr entryPoint)
+ unsigned int numheappages)
+{
+#if USE_MPROTECT_SNAPSHOT
+ mprot_snapshot_init(numbackingpages, numsnapshots, nummemoryregions, numheappages);
+#else
+ fork_snapshot_init(numbackingpages, numsnapshots, nummemoryregions, numheappages);
+#endif
+}
+
+void startExecution(ucontext_t *context, VoidFuncPtr entryPoint)
{
#if USE_MPROTECT_SNAPSHOT
- mprot_snapshot_init(numbackingpages, numsnapshots, nummemoryregions, numheappages, entryPoint);
+ mprot_startExecution(context, entryPoint);
#else
- fork_snapshot_init(numbackingpages, numsnapshots, nummemoryregions, numheappages, entryPoint);
+ fork_startExecution(context, entryPoint);
#endif
}