Skip to content

Instantly share code, notes, and snippets.

@vanaur
Created August 13, 2024 11:21
Show Gist options
  • Select an option

  • Save vanaur/16a3e2cfbbf7f664a99639489c08561a to your computer and use it in GitHub Desktop.

Select an option

Save vanaur/16a3e2cfbbf7f664a99639489c08561a to your computer and use it in GitHub Desktop.
pseudo-Jitting code in F#
open System
open System.Runtime.InteropServices
type AddFunction = delegate of int * int -> int
[<DllImport("libc.so.6", SetLastError = true)>]
extern nativeint mmap(nativeint addr, uint32 length, int prot, int flags, int fd, int offset)
[<DllImport("libc.so.6", SetLastError = true)>]
extern int munmap(nativeint addr, uint32 length)
let PROT_READ = 0x1
let PROT_WRITE = 0x2
let PROT_EXEC = 0x4
let MAP_PRIVATE = 0x02
let MAP_ANONYMOUS = 0x20
let executeAddFunction (addCode: byte[]) (a: int) (b: int) =
let memSize = addCode.Length
let executableMemory =
if RuntimeInformation.IsOSPlatform OSPlatform.Windows then
failwith "Only work for Linux"
else
let memory = mmap(0n, uint32 memSize, PROT_READ ||| PROT_WRITE ||| PROT_EXEC, MAP_PRIVATE ||| MAP_ANONYMOUS, -1, 0)
if memory = -1n
then raise (new InvalidOperationException("mmap failed"))
else memory
try
Marshal.Copy(addCode, 0, executableMemory, memSize)
let addFunction = Marshal.GetDelegateForFunctionPointer(executableMemory, typeof<AddFunction>) :?> AddFunction
let result = addFunction.Invoke(a, b)
result
finally
munmap(executableMemory, uint32 memSize) |> ignore
let addCode = [|
0x55uy; // push rbp
0x48uy; 0x89uy; 0xe5uy; // mov rbp, rsp
0x89uy; 0x7duy; 0xfcuy; // mov [rbp-4], edi
0x89uy; 0x75uy; 0xf8uy; // mov [rbp-8], esi
0x8buy; 0x55uy; 0xfcuy; // mov edx, [rbp-4]
0x8buy; 0x45uy; 0xf8uy; // mov eax, [rbp-8]
0x01uy; 0xd0uy; // add eax, edx
0x5duy; // pop rbp
0xc3uy // ret
|]
let a = 7
let b = 5
let result = executeAddFunction addCode a b
printfn "%d + %d = %d" a b result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment