Skip to content

Commit

Permalink
Start translating gadgets into aarch64
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Aug 17, 2018
1 parent f15ce9a commit e221670
Show file tree
Hide file tree
Showing 18 changed files with 1,130 additions and 9 deletions.
113 changes: 113 additions & 0 deletions jit/gadgets-aarch64/bits.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include "gadgets.h"

.macro do_shift type, size, s
.irp arg, reg_c,imm
.gadget \type\size\()_\arg
.ifc \arg,imm
ldr w8, [_ip]
ands w8, w8, \size-1
.else
ands w8, _ecx, \size-1
.endif
b.eq 1f

# shift by one less, then by one more
# that way we can retrieve the last bit shifted out for calculating CF and OF
.ifc \type,shl
sub w8, w8, 1
lsl _tmp, _tmp, w8
ubfx w9, _tmp, \size-1, 1
ubfx w10, _tmp, \size-2, 1
lsl _tmp, _tmp, 1
eor w10, w10, w9
strb w9, [_cpu, CPU_cf]
strb w10, [_cpu, CPU_of]
.else
brk 1
.endif

.ifin(\type, shl,shr,sar)
setf_zsp \s
clearf_a
.endifin
1:
.ifc \arg,imm
gret 1
.else
gret
.endif
.endr
.endm

.irp type, shl,shr,sar,rol,ror
.irp size, 8,16,32
ss \size, do_shift, \type
.endr
.gadget_array \type
.endr

.macro do_shiftd op, arg
.macro x name, reg
.gadget \op\()_\arg\()32_\name
brk 1
/*
.ifc \arg,imm
pushq %rcx
movb (%_ip), %cl
.endif
testb $(32 - 1), %cl
jz 1f
\op %cl, %\reg, %tmpd
setf_oc
setf_zsp %tmpd, l
1:
.ifc \arg,imm
popq %rcx
gret 1
.else
gret
.endif
*/
.endm
.each_reg x
.purgem x
.gadget_array \op\()_\arg
.endm
.irp op, shrd,shld
.irp arg, imm,cl
do_shiftd \op, \arg
.endr
.endr

.macro do_bt_w8
lsr w8, w8, _tmp
and w8, w8, 1
strb w8, [_cpu, CPU_cf]
.endm

.gadget bt32_mem
add _addr, _addr, _tmp, lsr 3
read_prep 32
ldr w8, [_xaddr]
do_bt_w8
gret 1

.macro x name reg
.gadget bt32_\name
mov w8, \reg
do_bt_w8
gret
.endm
.each_reg x
.purgem x

.gadget_array bt

.macro x name reg
.gadget bswap_\name
rev \reg, \reg
gret
.endm
.each_reg x
.purgem x
.gadget_list bswap, REG_LIST
184 changes: 184 additions & 0 deletions jit/gadgets-aarch64/control.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include "gadgets.h"

.gadget call
sub _esp, _esp, 4
mov _addr, _esp
write_prep 32
ldr w8, [_ip, 16]
str w8, [_xaddr]
write_done 32
ldr _ip, [_ip, 8]
b jit_ret_chain

.gadget call_indir
sub _esp, _esp, 4
mov _addr, _esp
ldr w8, [_ip, 8]
str w8, [_xaddr]
write_done 32
mov _eip, _tmp
b jit_ret

.gadget ret
mov _addr, _esp
ldr w8, [_ip, 8]
add _esp, _esp, w8
read_prep 32
ldr _eip, [_xaddr]
b jit_ret

.gadget jmp_indir
mov _eip, _tmp
b jit_ret
.gadget jmp
ldr _ip, [_ip]
b jit_ret_chain
.gadget jcxz
cbnz _ecx, 1f
ldr _ip, [_ip]
b jit_ret_chain
1:
ldr _ip, [_ip, 8]
b jit_ret_chain

#define COND_LIST o,c,z,cz,s,p,sxo,sxoz
#define IMPLEMENTED_CONDS c,z,cz,s,p,sxo,sxoz

.macro check_res
cmpl $0, CPU_res(%_cpu)
.endm
.macro check_cf
cmpb $0, CPU_cf(%_cpu)
.endm

.macro check_res_or_flag resflag, flag, target
ldr w8, [_cpu, CPU_flags_res]
tbz w8, \resflag, 2f
ldr w8, [_cpu, CPU_eflags]
tbz w8, \flag, 2f
b \target
2:
.endm

.macro do_jump cond, target
# please tell me if you know a better way
.ifc \cond,o
.else; .ifc \cond,c
ldrb w8, [_cpu, CPU_cf]
cbnz w8, \target
.else; .ifc \cond,z
check_res_or_flag 1/*ZF_RES*/, 6/*ZF_FLAG*/, \target
ldr w8, [_cpu, CPU_res]
cbz w8, \target
.else; .ifc \cond,cz
ldrb w8, [_cpu, CPU_cf]
cbnz w8, \target
check_res_or_flag 1/*ZF_RES*/, 6/*ZF_FLAG*/, \target
ldr w8, [_cpu, CPU_res]
cbz w8, \target
.else; .ifc \cond,s
check_res_or_flag 2/*SF_RES*/, 7/*SF_FLAG*/, \target
ldr w8, [_cpu, CPU_res]
cmp w8, 0
b.lt \target
.else; .ifc \cond,p
check_res_or_flag 0/*PF_RES*/, 2/*PF_FLAG*/, \target
# this is so sad
ldr w8, [_cpu, CPU_res]
uxtb w8, w8
fmov s0, w8
cnt v0.8b, v0.8b
uaddlv h0, v0.8b
fmov w8, s0
tbz w8, 0, \target
.else; .ifc \cond,sxo
ldr w8, [_cpu, CPU_res]
cmp w8, 0
cset w8, lt
ldrb w9, [_cpu, CPU_of]
cmp w8, w9
b.eq \target
.else; .ifc \cond,sxoz
ldr w8, [_cpu, CPU_res]
cmp w8, 0
b.eq \target
cset w8, lt
ldrb w9, [_cpu, CPU_of]
cmp w8, w9
b.eq \target
.endif; .endif; .endif; .endif; .endif; .endif; .endif; .endif
.endm

.irp cond, IMPLEMENTED_CONDS
.gadget jmp_\cond
do_jump \cond, 1f
ldr _ip, [_ip, 8]
b jit_ret_chain
1: ldr _ip, [_ip]
b jit_ret_chain

.gadget set_\cond
do_jump \cond, 1f
mov _tmp, 0
gret
1: mov _tmp, 1
gret
.gadget setn_\cond
do_jump \cond, 1f
mov _tmp, 1
gret
1: mov _tmp, 0
gret

.gadget skip_\cond
do_jump \cond, 1f
gret 1
1: ldr x8, [_ip]
add _ip, _ip, x8
gret 1
.gadget skipn_\cond
do_jump \cond, 1f
ldr x8, [_ip]
add _ip, _ip, x8
1: gret 1
.endr
.gadget_list jmp, COND_LIST
.gadget_list set, COND_LIST
.gadget_list setn, COND_LIST
.gadget_list skip, COND_LIST
.gadget_list skipn, COND_LIST

.gadget pushf
save_c
mov x0, _cpu
bl helper_collapse_flags
restore_c

sub _esp, _esp, 4
mov _addr, _esp
write_prep 32
ldr x8, [_cpu, CPU_eflags]
str x8, [_xaddr]
write_done 32
gret

.gadget popf
mov _addr, _esp
read_prep 32
ldr x8, [_xaddr]
add _esp, _esp, 4

save_c
mov x0, _cpu
bl helper_expand_flags
restore_c
gret

.gadget sahf
ubfx w8, _eax, 8, 8
strb w8, [_cpu, CPU_eflags]
save_c
mov x0, _cpu
bl helper_expand_flags
restore_c
gret
63 changes: 63 additions & 0 deletions jit/gadgets-aarch64/entry.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "emu/interrupt.h"
#include "gadgets.h"

.global jit_enter
.type jit_enter,function
jit_enter:
stp x18, x19, [sp, -0x60]!
stp x20, x21, [sp, 0x10]
stp x22, x23, [sp, 0x20]
stp x24, x25, [sp, 0x30]
stp x26, x27, [sp, 0x40]
stp x28, x29, [sp, 0x50]
add _ip, x0, JIT_BLOCK_code
# cpu is already x1
add _tlb, x2, TLB_entries
ldr _eax, [_cpu, CPU_eax]
ldr _ebx, [_cpu, CPU_ebx]
ldr _ecx, [_cpu, CPU_ecx]
ldr _edx, [_cpu, CPU_edx]
ldr _esi, [_cpu, CPU_esi]
ldr _ebp, [_cpu, CPU_ebp]
ldr _esp, [_cpu, CPU_esp]
gret

.global jit_ret_chain
jit_ret_chain:
cmp _ip, 0
b.lt jit_ret
gret

.global jit_ret
jit_ret:
# load -1
mvn _tmp, wzr
# fallthrough

.global jit_exit
jit_exit:
str _eax, [_cpu, CPU_eax]
str _ebx, [_cpu, CPU_ebx]
str _ecx, [_cpu, CPU_ecx]
str _edx, [_cpu, CPU_edx]
str _esi, [_cpu, CPU_esi]
str _ebp, [_cpu, CPU_ebp]
str _esp, [_cpu, CPU_esp]
str _eip, [_cpu, CPU_eip]
ldp x28, x29, [sp, 0x50]
ldp x26, x27, [sp, 0x40]
ldp x24, x25, [sp, 0x30]
ldp x22, x23, [sp, 0x20]
ldp x20, x21, [sp, 0x10]
ldp x18, x19, [sp], 0x60
# _tmp is already x0
ret

.gadget interrupt
ldr _tmp, [_ip]
ldr _eip, [_ip, 8]
b jit_exit

.gadget exit
ldr _eip, [_ip]
b jit_ret
Loading

0 comments on commit e221670

Please sign in to comment.