Skip to content

Instantly share code, notes, and snippets.

@carnaval
Created February 2, 2016 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carnaval/3c9c5d27504da128d38b to your computer and use it in GitHub Desktop.
Save carnaval/3c9c5d27504da128d38b to your computer and use it in GitHub Desktop.
function to_mc(asm)
aname = tempname()
open(aname, "w") do io
write(io, asm)
write(io, '\n')
end
oname = tempname()
run(`as --64 $aname -o $oname`)
mname = tempname()
run(`objcopy -O binary $oname $mname`)
read(open(mname, "r"))
end
function call_mc(mc :: Vector{UInt8}, arg1 :: UInt64)
mem = Mmap.mmap(Vector{UInt8}, length(mc))
copy!(mem, mc)
addr = pointer(mem)
res = ccall(:mprotect, Cint, (Ptr{Void}, Csize_t, Cint), addr, length(mem), 0x4 | 0x1) # PROT_READ | PROT_EXEC
if res != 0
error("mprotect error")
end
ccall(addr, UInt64, (UInt64,), arg1)
end
function do_it(code, arg1)
asm = """
/* push %rdi first argument is in %rdi */
$code
pop %rax /* return value goes in %rax */
ret
"""
mc = to_mc(asm)
println("ASM:")
println(asm)
call_mc(mc, UInt(42))
end
function emit(io::IO, x :: Integer)
x = convert(UInt, x)
println(io, "push \$$x")
end
function emit(io::IO, x :: Expr)
if x.head === :call
if x.args[1] === :+ && length(x.args) == 3
println(io, "/* start $x */")
emit(io, x.args[2])
emit(io, x.args[3])
println(io, "pop %rax")
println(io, "pop %rbx")
println(io, "add %rbx, %rax")
println(io, "push %rax")
println(io, "/* end $x */")
return
end
end
error("not done yet $x")
end
function run_expr(expr)
io = IOBuffer()
emit(io, expr)
seekstart(io)
res = do_it(readstring(io), UInt(42))
println("Expr : ", expr)
println("Result : ", res)
res
end
run_expr(:((2 + 3) + (4 + 3)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment