// jitproto.c #include #include #include typedef long(*fn)(long); fn compile_identity(void) { // Allocate some memory and set its permissions correctly. In particular, we // need PROT_EXEC (which isn't normally enabled for data memory, e.g. from // malloc()), which tells the processor it's ok to execute it as machine // code. char *memory = mmap(NULL, // address 4096, // size PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, // fd (not used here) 0); // offset (not used here) if (!memory) { perror("failed to allocate memory"); exit(1); } int i = 0; // mov %rdi, %rax memory[i++] = 0x48; // REX.W prefix memory[i++] = 0x8b; // MOV opcode, register/register memory[i++] = 0xc7; // MOD/RM byte for %rdi -> %rax // ret memory[i++] = 0xc3; // RET opcode return (fn) memory; } int main() { fn f = compile_identity(); int i; for (i = 0; i < 10; ++i) printf("f(%d) = %ld\n", i, (*f)(i)); munmap(f, 4096); return 0; }