Use getcontext/setcontext rather than twiddling %rip master
authorMatt Mullins <mmullins@mmlx.us>
Sat, 21 Sep 2013 23:17:58 +0000 (23:17 +0000)
committerMatt Mullins <mmullins@mmlx.us>
Sat, 21 Sep 2013 23:17:58 +0000 (23:17 +0000)
This technically slows the main loop down a little, but makes it a lot less
machine-specific code.

mmap_everything.c

index 13d343d..d7d7ada 100644 (file)
@@ -1,35 +1,29 @@
-#define _GNU_SOURCE foo
-
 #include <limits.h>
 #include <signal.h>
 #include <sys/mman.h>
 #include <sys/types.h>
-#include <sys/ucontext.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
+#include <ucontext.h>
 #include <unistd.h>
 
 #define MAX_BITS (sizeof(size_t) * CHAR_BIT - 1)
 
+static ucontext_t ctx;
+
 int dummy = 13;
 int *pi;
 
 static void catch_sigsegv(int signal, siginfo_t *info, void *p) {
-       (void)(signal);
-
-       ucontext_t *uctx = (ucontext_t*)p;
-       greg_t rip = uctx->uc_mcontext.gregs[REG_RIP];
+       (void)(signal); (void)(p);
 
        fprintf(stderr, "Caught a segfault at %p\n", info->si_addr);
        fflush(stderr);
 
-       // Point it at a variable we can always load
        pi = &dummy;
-       // Roll back %rip so we can reload *pi before dereferencing
-       rip -= 7; // length of mov    0x2006b4(%rip),%rax        # 0x6012b0 <pi>
-       uctx->uc_mcontext.gregs[REG_RIP] = rip;
+       setcontext(&ctx);
 }
 
 int main() {
@@ -89,6 +83,9 @@ int main() {
                pi = (void*)(pvalue);
                printf("*%p = ", (void*)pi);
                fflush(stdout);
+
+               getcontext(&ctx);
+
                data = *pi;
                if (pi != &dummy) {
                        printf("%04x\n", data);
@@ -99,5 +96,5 @@ int main() {
                if (munmap((void*)(pvalue & ~0xFFFL), 4096)) {
                        perror("munmap");
                }
-       } while (data == 0 || pi == &dummy);
+       } while (pi == &dummy || data == 0);
 }