Skip to content

Instantly share code, notes, and snippets.

@jumbojets
Last active November 2, 2024 02:57
Show Gist options
  • Save jumbojets/1d7008901826eb9de1f2aa608f368847 to your computer and use it in GitHub Desktop.
Save jumbojets/1d7008901826eb9de1f2aa608f368847 to your computer and use it in GitHub Desktop.
# modifies following code to work on macos
# https://eli.thegreenplace.net/2017/adventures-in-jit-compilation-part-4-in-python/
# interesting: https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon?language=objc
import ctypes, mmap as mmap_flags
libc = ctypes.cdll.LoadLibrary(None)
mmap = libc.mmap
mmap.restype = ctypes.c_void_p
mmap.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_size_t)
mprotect = libc.mprotect
mprotect.restype = ctypes.c_int
mprotect.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int)
CODE_SIZE = 1024
code_address = mmap(None, CODE_SIZE, mmap_flags.PROT_READ | mmap_flags.PROT_WRITE, mmap_flags.MAP_ANON | mmap_flags.MAP_PRIVATE, -1, 0)
if code_address == -1:
raise OSError('mmap failed to allocate memory')
code = b'\x00\x7c\x00\x9b\xc0\x03\x5f\xd6'
assert len(code) <= CODE_SIZE
ctypes.memmove(code_address, code, len(code))
if mprotect(code_address, CODE_SIZE, mmap_flags.PROT_READ | mmap_flags.PROT_EXEC, 0) < 0:
raise OSError('mprotect failed to make memory executable')
JittedFuncType = ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long)
func = JittedFuncType(code_address)
print(func(100)) # 10000
import ctypes, mmap as mmap_flags, subprocess
libc = ctypes.cdll.LoadLibrary(None)
mmap = libc.mmap
mmap.restype = ctypes.c_void_p
mmap.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_size_t)
mprotect = libc.mprotect
mprotect.restype = ctypes.c_int
mprotect.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_int, ctypes.c_int)
c_code = '''
int square(int x) {
return x * x;
}
'''
command = ['clang', '-x', 'c', '-O2', '-fPIC', '-c', '-', '-o', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
machine_code, _ = process.communicate(input=c_code.encode())
code_size = len(machine_code)
code_address = mmap(None, code_size, mmap_flags.PROT_READ | mmap_flags.PROT_WRITE, mmap_flags.MAP_ANON | mmap_flags.MAP_PRIVATE, -1, 0)
if code_address == -1:
raise OSError('mmap failed to allocate memory')
ctypes.memmove(code_address, machine_code, code_size)
if mprotect(code_address, code_size, mmap_flags.PROT_READ | mmap_flags.PROT_EXEC, 0) < 0:
raise OSError('mprotect failed to make memory executable')
JittedFuncType = ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long)
func = JittedFuncType(code_address)
print(func(100)) # XXX: ILLEGAL HARDWARE INSTRUCTION (not jumping to method inside machine code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment