45 lines
1.2 KiB
C
45 lines
1.2 KiB
C
// jitproto.c
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/mman.h>
|
|
|
|
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 %rsi -> %rax
|
|
|
|
// ret
|
|
memory[i++] = 0xc3; // RET opcode
|
|
|
|
return (long(*)(long)) memory;
|
|
}
|
|
|
|
int main() {
|
|
fn f = compile_identity();
|
|
int i;
|
|
for (i = 0; i < 10; ++i)
|
|
printf("f(%d) = %ld\n", i, (*f)(i));
|
|
munmap((void*) f, 4096);
|
|
return 0;
|
|
}
|