From 9cd9f2aa53c665cb9024e03283010f9e875cad56 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Fri, 7 Oct 2016 23:58:05 -0400 Subject: Implement jit_hop and jit_hop for jrp --- .bin/jrp.c | 156 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 62 deletions(-) diff --git a/.bin/jrp.c b/.bin/jrp.c index 523a5d49..8c436163 100755 --- a/.bin/jrp.c +++ b/.bin/jrp.c @@ -4,6 +4,7 @@ exec cc -Wall -Wextra $@ -o $(dirname $0)/jrp $0 #include #include +#include #include #include #include @@ -13,9 +14,30 @@ typedef long long value; typedef unsigned long long uvalue; typedef value *(*fptr)(value *); +static void rt_print_ascii(value val) { + printf("%c\n", (char)val); +} +static void rt_print_bin(value val) { + static char buf[sizeof(value) * 8 + 1]; + uvalue uval = val; + int i = sizeof(buf); + do { + buf[--i] = '0' + (uval & 1); + } while (uval >>= 1); + printf("%s\n", &buf[i]); +} +static void rt_print_oct(value val) { + printf("%llo\n", val); +} +static void rt_print_dec(value val) { + printf("%lld\n", val); +} +static void rt_print_hex(value val) { + printf("%llx\n", val); +} + enum { HOP_NOP = 0x90666666, // nop - HOP_RET = 0x906666c3, // ret HOP_DROP = 0x9066665f, // pop rdi HOP_DUP = 0x90666657, // push rdi HOP_SWAP = 0x244c8748, // xchg rdi, [rsp] @@ -32,6 +54,7 @@ enum { enum { FOP_PROL = 0x5ffc8948e5894855, // push rbp; mov rbp, rsp; mov rsp, rdi; pop rdi FOP_EPIL = 0x5dec8948e0894857, // push rdi; mov rax, rsp; mov rsp, rbp; pop rbp + FOP_RET = 0x90666690666666c3, // ret FOP_CRT = 0xb848906666e58748, // xchg rsp, rbp; mov rax, strict qword 0 FOP_CALL = 0x90665fe58748d0ff, // call rax; xchg rsp, rbp; pop rdi FOP_PUSH = 0xbf48909066666657, // push rdi; mov rdi, strict qword 0 @@ -42,80 +65,89 @@ enum { FOP_SHR = 0x5f242cd348f98948, // mov rcx, rdi; shr qword [rsp], cl; pop rdi }; -#define FOP(a, b) ((op)(b) << 32 | (op)(a)) +static int page; -#define JIT_PUSH(p, x) { \ - *(p)++ = FOP_PUSH; \ - *(p)++ = x; \ -} +static int radix = 10; -#define JIT_CALL(p, fn) { \ - *(p)++ = FOP_CRT; \ - *(p)++ = (op)(fn); \ - *(p)++ = FOP_CALL; \ -} +static value *stack; -static void rt_print_ascii(value val) { - printf("%c\n", (char)val); -} +static struct { + op *base; + op *ptr; + op hop; +} code; -static void rt_print_bin(value val) { - static char buf[sizeof(value) * 8 + 1]; - uvalue uval = val; - int i = sizeof(buf); - do { - buf[--i] = '0' + (uval & 1); - } while (uval >>= 1); - printf("%s\n", &buf[i]); +static void jit_hop(op hop) { + if (code.hop) { + *code.ptr++ = hop << 32 | code.hop; + code.hop = 0; + } else { + code.hop = hop; + } } -static void rt_print_oct(value val) { - printf("%llo\n", val); +static void jit_fop(op fop) { + if (code.hop) jit_hop(HOP_NOP); + *code.ptr++ = fop; } -static void rt_print_dec(value val) { - printf("%lld\n", val); -} +static void jit(char *src) { + int error; -static void rt_print_hex(value val) { - printf("%llx\n", val); + code.ptr = code.base; + jit_fop(FOP_PROL); + + jit_fop(FOP_PUSH); + jit_fop(7); + jit_fop(FOP_PUSH); + jit_fop(10); + jit_fop(FOP_PUSH); + jit_fop(9); + jit_fop(FOP_MUL); + jit_hop(HOP_ADD); + jit_hop(HOP_DUP); + jit_hop(HOP_DUP); + jit_hop(HOP_DUP); + jit_hop(HOP_DUP); + jit_fop(FOP_CRT); + jit_fop((op)rt_print_ascii); + jit_fop(FOP_CALL); + jit_fop(FOP_CRT); + jit_fop((op)rt_print_bin); + jit_fop(FOP_CALL); + jit_fop(FOP_CRT); + jit_fop((op)rt_print_oct); + jit_fop(FOP_CALL); + jit_fop(FOP_CRT); + jit_fop((op)rt_print_dec); + jit_fop(FOP_CALL); + jit_fop(FOP_CRT); + jit_fop((op)rt_print_hex); + jit_fop(FOP_CALL); + + jit_fop(FOP_EPIL); + jit_fop(FOP_RET); + + error = mprotect(code.base, page, PROT_READ | PROT_EXEC); + if (error) err(EX_OSERR, "mprotect"); + + stack = ((fptr)code.base)(stack); + + error = mprotect(code.base, page, PROT_READ | PROT_WRITE); + if (error) err(EX_OSERR, "mprotect"); } int main() { - int error; - int page = getpagesize(); - - value *base = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); - if (base == MAP_FAILED) err(EX_OSERR, "mmap"); - value *stack = base + page / sizeof(value) - 1; - - op *ops = mmap(0, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); - if (ops == MAP_FAILED) err(EX_OSERR, "mmap"); - - op *p = ops; - *p++ = FOP_PROL; - JIT_PUSH(p, 7); - JIT_PUSH(p, 10); - JIT_PUSH(p, 9); - *p++ = FOP_MUL; - *p++ = FOP(HOP_ADD, HOP_DUP); - *p++ = FOP(HOP_DUP, HOP_DUP); - *p++ = FOP(HOP_DUP, HOP_NOP); - JIT_CALL(p, rt_print_ascii); - JIT_CALL(p, rt_print_bin); - JIT_CALL(p, rt_print_oct); - JIT_CALL(p, rt_print_dec); - JIT_CALL(p, rt_print_hex); - *p++ = FOP_EPIL; - *p++ = FOP(HOP_RET, HOP_NOP); - - error = mprotect(ops, page, PROT_READ | PROT_EXEC); - if (error) err(EX_OSERR, "mprotect"); + page = getpagesize(); + + code.base = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); + if (code.base == MAP_FAILED) err(EX_OSERR, "mmap"); - fptr fn = (fptr)ops; - stack = fn(stack); + stack = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); + if (stack == MAP_FAILED) err(EX_OSERR, "mmap"); + stack += page / sizeof(value) - 1; - printf("%lld\n", *stack); + jit("7 10 9 * + :::: , b. o. d. h."); - return 0; + return EX_OK; } -- cgit 1.4.1