Skip to content

Instantly share code, notes, and snippets.

@MrSmith33
Last active February 9, 2017 18:10
Show Gist options
  • Save MrSmith33/61bb9cbcab18af52da4d910c5372b6f9 to your computer and use it in GitHub Desktop.
Save MrSmith33/61bb9cbcab18af52da4d910c5372b6f9 to your computer and use it in GitHub Desktop.
Random JIT playground
module main;
import std.stdio;
void main()
{
run_from_rwx();
}
version(Posix)
{
ubyte[] allocate(size_t bytes, bool is_executable)
{
import core.sys.posix.sys.mman : mmap, MAP_ANON, PROT_READ,
PROT_WRITE, PROT_EXEC, MAP_PRIVATE, MAP_FAILED;
if (!bytes) return null;
int protection = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
auto p = mmap(null, bytes, protection, MAP_PRIVATE | MAP_ANON, -1, 0);
if (p is MAP_FAILED) return null;
return cast(ubyte[])p[0 .. bytes];
}
bool deallocate(ubyte[] b)
{
import core.sys.posix.sys.mman : munmap;
if (b.ptr) munmap(b.ptr, b.length) == 0 || assert(0);
return true;
}
}
else version(Windows)
{
import core.sys.windows.windows : VirtualAlloc, VirtualFree, MEM_COMMIT,
PAGE_READWRITE, MEM_RELEASE, PAGE_EXECUTE_READWRITE, MEM_RESERVE;
ubyte[] allocate(size_t bytes, bool is_executable)
{
if (!bytes) return null;
int protection = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
auto p = VirtualAlloc(null, bytes, MEM_COMMIT | MEM_RESERVE, protection);
if (p == null)
return null;
return cast(ubyte[])p[0 .. bytes];
}
bool deallocate(ubyte[] b)
{
return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0;
}
}
ubyte[] alloc_executable_memory(size_t bytes)
{
return allocate(bytes, true);
}
version(Windows)
{
ubyte[] code = [
0x48, 0x89, 0xC8, // mov rax,rcx
0x48, 0x83, 0xC0, 0x04, // add rax,4
0xC3, // ret
];
}
else version(Posix)
{
ubyte[] code = [
0x48, 0x89, 0xf8, // mov rax,rdi
0x48, 0x83, 0xc0, 0x04, // add rax,0x4
0xc3, // ret
];
}
void emit_code_into_memory(ubyte[] m)
{
m[0..code.length] = code;
}
long test(long a) {
return a + 4;
}
const size_t SIZE = 1024;
void run_from_rwx()
{
ubyte[] m = alloc_executable_memory(SIZE);
writefln("alloc %s %s", m.ptr, m.length);
emit_code_into_memory(m);
alias JittedFunc = long function(long);
JittedFunc func = cast(JittedFunc)m.ptr;
long result = func(2);
writefln("result = %s", result);
//void* code_ptr = &test;
//printMem(code_ptr, 5);
}
void printMem(void* ptr, size_t lines, size_t width = 8)
{
foreach(i; 0..lines)
{
auto offset = i * width;
writefln("%(%02x %)", ptr[offset..offset+width]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment