/* * Quick simulation of what a JIT does. * This will not work on ELFv1. */ #include #include #include #include #include #include #include #include void *membuffer; void zeroheader(void) __used; void zeroret(void) __used; void trailer(void) __used; /* Begin template code. */ void zeroheader() { __asm __volatile ("nop;"); return; } void zeroret() { __asm __volatile ("nop;"); return; } void trailer() { /* Do not call me -- function body not part of bcopy */ __asm __volatile ("nop;"); } /* End template code. */ /* * SIGSEGV handler to copy the function to the jit page AFTER * we have called it, to ensure all the moving parts are working. */ void do_jit(void) { mprotect(membuffer, 4096, PROT_READ|PROT_WRITE); memmove(membuffer, &zeroheader, MIN((&trailer - &zeroheader), 4096)); __compiler_membar(); mprotect(membuffer, 4096, PROT_READ|PROT_EXEC); return; } int main(int argc, char *argv[]) { printf("Setting up page\n"); membuffer = aligned_alloc(4096, 4096); if (!membuffer) { printf("Couldn't align buffer page"); return(1); } printf("Buffer @ %p\n", membuffer); void (*callme)(void) = (void (*)(void))(membuffer + (&zeroret - &zeroheader)); printf("Function pointer target: %p\n", &callme); signal(SIGSEGV, (sig_t)do_jit); printf("Signal handler installed.\n"); mprotect(membuffer, 4096, PROT_NONE); printf("Protected JIT page. About to call.\n"); /* * At this point we are branching to an empty page with zero protections. * The signal handler will copy the actual code over and fix up the protection. */ (callme)(); /* * Since we got here, everything is working properly. */ printf("Made it back to main().\n"); return (0); }