Implement shl

This commit is contained in:
Theodore Dubois 2018-05-22 16:33:00 -07:00
parent 45e9e5f5b6
commit 690efbc4b2
6 changed files with 52 additions and 46 deletions

View File

@ -51,4 +51,4 @@
jmp jit_ret
.endr
.gadget_array jmp, COND_LIST
.gadget_list jmp, COND_LIST

View File

@ -52,14 +52,8 @@
#define GADGET_LIST REG_LIST,imm,mem,addr
# an array of gadgets
.macro .gadget_array type, list:vararg
.macro _gadget_array_start name
.pushsection .rodata
.gadget_array_start \type
gadgets \type, \list
.popsection
.endm
.macro .gadget_array_start name
.global \name\()_gadgets
.type \name\()_gadgets,@object
\name\()_gadgets:
@ -74,6 +68,46 @@
.endr
.endm
.macro .gadget_list type, list:vararg
_gadget_array_start \type
gadgets \type, \list
.popsection
.endm
.macro .gadget_array type
_gadget_array_start \type
# sync with enum size
gadgets \type\()8, GADGET_LIST
gadgets \type\()16, GADGET_LIST
gadgets \type\()32, GADGET_LIST
.popsection
.endm
.macro setf_oc
seto CPU_of(%_cpu)
setc CPU_cf(%_cpu)
.endm
.macro setf_a src, dst, ss
mov\ss \src, CPU_op1(%_cpu)
mov\ss \dst, CPU_op2(%_cpu)
orl $AF_OPS, CPU_flags_res(%_cpu)
.endm
.macro clearf_a
andl $~AF_FLAG, CPU_eflags(%_cpu)
andl $~AF_OPS, CPU_flags_res(%_cpu)
.endm
.macro clearf_oc
movl $0, CPU_of(%_cpu)
movl $0, CPU_cf(%_cpu)
.endm
.macro setf_zsp res, ss
.ifnc \ss,l
movs\ss\()l \res, %_tmp
.endif
movl %_tmp, CPU_res(%_cpu)
orl $(ZF_RES|SF_RES|PF_RES), CPU_flags_res(%_cpu)
.endm
.macro save_c
push %rax
push %rcx

View File

@ -5,31 +5,6 @@
movl %_addr, %_tmp
gret
.macro setf_oc
seto CPU_of(%_cpu)
setc CPU_cf(%_cpu)
.endm
.macro setf_a src, dst, ss
mov\ss \src, CPU_op1(%_cpu)
mov\ss \dst, CPU_op2(%_cpu)
orl $AF_OPS, CPU_flags_res(%_cpu)
.endm
.macro clearf_a
andl $~AF_FLAG, CPU_eflags(%_cpu)
andl $~AF_OPS, CPU_flags_res(%_cpu)
.endm
.macro clearf_oc
movl $0, CPU_of(%_cpu)
movl $0, CPU_cf(%_cpu)
.endm
.macro setf_zsp res, ss
.ifnc \ss,l
movs\ss\()l \res, %_tmp
.endif
movl %_tmp, CPU_res(%_cpu)
orl $(ZF_RES|SF_RES|PF_RES), CPU_flags_res(%_cpu)
.endm
# this would have been just a few nice compact nested loops, but gas said "nuh uh"
#define ifin(thing, ...) irp da_op, __VA_ARGS__; .ifc thing,\da_op
@ -138,14 +113,7 @@
.irp size, 8,16,32
do_op_size \op, \size
.endr
.pushsection .rodata
.gadget_array_start \op
# sync with enum size
.irp size, 8,16,32
gadgets \op\size, GADGET_LIST
.endr
.popsection
.gadget_array \op
.endr
.irp op, inc,dec

View File

@ -35,7 +35,7 @@
.endm
.each_reg x
.purgem x
.gadget_array addr, REG_LIST
.gadget_list addr, REG_LIST
.macro x name, reg
.irp times, 1,2,4
@ -86,5 +86,3 @@ segfault:
addq $8, %rsp # pop return address
movl $INT_GPF, %_tmp
jmp jit_exit
.gadget_array, REG_LIST

View File

@ -9,7 +9,7 @@ enum arg {
arg_imm, arg_mem, arg_addr,
arg_count, arg_invalid,
// the following should not be synced with the list mentioned above (no gadgets implement them)
arg_modrm_val, arg_modrm_reg, arg_mem_addr, arg_gs,
arg_modrm_val, arg_modrm_reg, arg_mem_addr, arg_gs, arg_1,
};
enum size {
@ -40,6 +40,7 @@ GADGET_ARRAY(sub);
GADGET_ARRAY(and);
GADGET_ARRAY(or);
GADGET_ARRAY(xor);
GADGET_ARRAY(shl);
void gadget_call();
void gadget_ret();
@ -86,6 +87,10 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
else
arg = arg_mem;
break;
case arg_1:
arg = arg_imm;
*imm = 1;
break;
}
if (arg >= arg_count || gadgets[arg] == NULL) {
debugger;
@ -189,7 +194,7 @@ static inline void gen_op(struct gen_state *state, gadget_t *gadgets, enum arg a
#define ROL(count, val,z) UNDEFINED
#define ROR(count, val,z) UNDEFINED
#define SHL(count, val,z) UNDEFINED
#define SHL(count, val,z) los(shl, count, val, z)
#define SHR(count, val,z) UNDEFINED
#define SAR(count, val,z) UNDEFINED

View File

@ -94,6 +94,7 @@ if get_option('jit')
'emu/gen.c',
'emu/gadgets-x86/entry.S',
'emu/gadgets-x86/math.S',
'emu/gadgets-x86/shift.S',
'emu/gadgets-x86/control.S',
'emu/gadgets-x86/memory.S',
offsets,