+
+/** The initSnapShotRecord method initialized the snapshotting data
+ * structures for the mprotect based snapshot.
+ */
+static void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions)
+{
+ mprot_snap = (struct mprot_snapshotter *)model_malloc(sizeof(struct mprot_snapshotter));
+ mprot_snap->regionsToSnapShot = (struct MemoryRegion *)model_malloc(sizeof(struct MemoryRegion) * nummemoryregions);
+ mprot_snap->backingStoreBasePtr = (void *)model_malloc(sizeof(snapshot_page_t) * (numbackingpages + 1));
+ //Page align the backingstorepages
+ mprot_snap->backingStore = (snapshot_page_t *)PageAlignAddressUpward(mprot_snap->backingStoreBasePtr);
+ mprot_snap->backingRecords = (struct BackingPageRecord *)model_malloc(sizeof(struct BackingPageRecord) * numbackingpages);
+ mprot_snap->snapShots = (struct SnapShotRecord *)model_malloc(sizeof(struct SnapShotRecord) * numsnapshots);
+ mprot_snap->lastSnapShot = 0;
+ mprot_snap->lastBackingPage = 0;
+ mprot_snap->lastRegion = 0;
+ mprot_snap->maxRegions = nummemoryregions;
+ mprot_snap->maxBackingPages = numbackingpages;
+ mprot_snap->maxSnapShots = numsnapshots;
+}
+
+/** HandlePF is the page fault handler for mprotect based snapshotting
+ * algorithm.
+ */
+static void HandlePF(int sig, siginfo_t *si, void *unused)
+{
+ if (si->si_code == SEGV_MAPERR) {
+ model_print("Real Fault at %p\n", si->si_addr);
+ print_trace();
+ model_print("For debugging, place breakpoint at: %s:%d\n",
+ __FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+ void* addr = ReturnPageAlignedAddress(si->si_addr);
+
+ unsigned int backingpage = mprot_snap->lastBackingPage++; //Could run out of pages...
+ if (backingpage == mprot_snap->maxBackingPages) {
+ model_print("Out of backing pages at %p\n", si->si_addr);
+ exit(EXIT_FAILURE);
+ }
+
+ //copy page
+ memcpy(&(mprot_snap->backingStore[backingpage]), addr, sizeof(snapshot_page_t));
+ //remember where to copy page back to
+ mprot_snap->backingRecords[backingpage].basePtrOfPage = addr;
+ //set protection to read/write
+ if (mprotect(addr, sizeof(snapshot_page_t), PROT_READ | PROT_WRITE)) {
+ perror("mprotect");
+ // Handle error by quitting?
+ }
+}
+
+static void mprot_snapshot_init(unsigned int numbackingpages,
+ unsigned int numsnapshots, unsigned int nummemoryregions,
+ unsigned int numheappages, VoidFuncPtr entryPoint)
+{
+ /* Setup a stack for our signal handler.... */
+ stack_t ss;
+ ss.ss_sp = PageAlignAddressUpward(model_malloc(SIGSTACKSIZE + PAGESIZE - 1));
+ ss.ss_size = SIGSTACKSIZE;
+ ss.ss_flags = 0;
+ sigaltstack(&ss, NULL);
+
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART | SA_ONSTACK;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = HandlePF;
+#ifdef MAC
+ if (sigaction(SIGBUS, &sa, NULL) == -1) {
+ model_print("SIGACTION CANNOT BE INSTALLED\n");
+ exit(EXIT_FAILURE);
+ }