Skip to content

Instantly share code, notes, and snippets.

@eniton
Forked from stuartcarnie/main.m
Created December 9, 2012 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eniton/4244713 to your computer and use it in GitHub Desktop.
Save eniton/4244713 to your computer and use it in GitHub Desktop.
Demonstrates we can now support limited JIT compilation on recent versions of iOS (assuming Apple approves entitlements at some future point)
//
// main.m
// ProtectTest
// Demonstrates newer versions of iOS now support PROT_EXEC pages, for just-in-time compilation.
//
// Must be compiled with Thumb disabled
//
// Created by Stuart Carnie on 3/4/11.
// Copyright 2011 Manomio LLC. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include <limits.h> /* for PAGESIZE */
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
typedef int (*inc_t)(int a);
inc_t _inc = NULL;
int
main(void)
{
uint32_t code[] = {
0xe2800001, // add r0, r0, #1
0xe12fff1e, // bx lr
};
uint32_t *p;
/* Allocate a buffer; it will have the default
protection of PROT_READ|PROT_WRITE. */
p = malloc(1024+PAGESIZE-1);
if (!p) {
perror("Couldn't malloc(1024)");
exit(errno);
}
/* Align to a multiple of PAGESIZE, assumed to be a power of two */
p = (uint32_t *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
// copy instructions to function
p[0] = code[0];
p[1] = code[1];
/* Mark the buffer read / execute. */
if (mprotect(p, 1024, PROT_READ | PROT_EXEC)) {
perror("Couldn't mprotect");
exit(errno);
}
_inc = (inc_t)p;
int a = 1;
a = _inc(a);
printf("%d\n", a); // as expected, echos 2
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment