Skip to content

Commit

Permalink
Foundations of jit, no actual compiling yet
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 3, 2018
1 parent 18c71cb commit 498c17b
Show file tree
Hide file tree
Showing 23 changed files with 562 additions and 28 deletions.
1 change: 1 addition & 0 deletions emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ union xmm_reg {

struct cpu_state {
struct mem *mem;
struct jit *jit;

// assumes little endian (as does literally everything)
#define _REG(n) \
Expand Down
19 changes: 7 additions & 12 deletions emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
__no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
DECLARE_LOCALS;

dword_t addr_offset = 0;
byte_t insn;
uint64_t imm;
struct modrm modrm;
#define READIMM_(name, size) _READIMM(name, size); TRACE("imm %llx ", (long long) name)
#define READADDR READIMM_(addr_offset, 32); addr += addr_offset
#define READINSN _READIMM(insn, 8); TRACE("%02x ", insn)
#define READIMM READIMM_(imm, OP_SIZE)
#define READIMM8 READIMM_(imm, 8)
#define READIMM16 READIMM_(imm, 16)

restart:
TRACE("%d %08x\t", current->pid, cpu->eip);
TRACEIP();
READINSN;
switch (insn) {
#define MAKE_OP(x, OP, op) \
Expand Down Expand Up @@ -168,10 +167,7 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0x9f: TRACEI("setnle\t");
READMODRM; SET(!LE, modrm_val); break;

case 0xa2:
TRACEI("cpuid");
do_cpuid(&cpu->eax, &cpu->ebx, &cpu->ecx, &cpu->edx);
break;
case 0xa2: TRACEI("cpuid"); CPUID(); break;

case 0xa3: TRACEI("bt reg, modrm");
READMODRM; BT(modrm_reg, modrm_val,); break;
Expand Down Expand Up @@ -310,16 +306,15 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0x5e: TRACEI("pop osi"); POP(osi); break;
case 0x5f: TRACEI("pop odi"); POP(odi); break;

case 0x65: TRACELN("segment gs");
addr += cpu->tls_ptr; goto restart;
case 0x65: TRACELN("segment gs"); SEG_GS(); goto restart;

case 0x66:
#if OP_SIZE == 32
TRACELN("entering 16 bit mode");
return glue(DECODER_NAME, 16)(DECODER_PASS_ARGS);
RETURN(glue(DECODER_NAME, 16)(DECODER_PASS_ARGS));
#else
TRACELN("entering 32 bit mode");
return glue(DECODER_NAME, 32)(DECODER_PASS_ARGS);
RETURN(glue(DECODER_NAME, 32)(DECODER_PASS_ARGS));
#endif

case 0x67: TRACEI("address size prefix (ignored)"); goto restart;
Expand Down Expand Up @@ -725,5 +720,5 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
UNDEFINED;
}
TRACELN("");
FINISH;
RETURN(-1); // everything is ok.
}
44 changes: 44 additions & 0 deletions emu/gadgets-x86/gadgets.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "gadgets.h"
#include "cpu-offsets.h"

.global jit_enter
.type jit_enter,function
jit_enter:
push %rbp
push %rbx
leaq JIT_BLOCK_code(%rsi), %ip
movq %rdi, %cpu
movl CPU_eax(%cpu), %eax
movl CPU_ebx(%cpu), %ebx
movl CPU_ecx(%cpu), %ecx
movl CPU_edx(%cpu), %edx
movl CPU_esi(%cpu), %esi
movl CPU_edi(%cpu), %edi
movl CPU_ebp(%cpu), %ebp
movl CPU_esp(%cpu), %xsp
# TODO more of those
endgadget

.global jit_exit
jit_exit:
movl %eax, CPU_eax(%cpu)
movl %ebx, CPU_ebx(%cpu)
movl %ecx, CPU_ecx(%cpu)
movl %edx, CPU_edx(%cpu)
movl %esi, CPU_esi(%cpu)
movl %edi, CPU_edi(%cpu)
movl %ebp, CPU_ebp(%cpu)
movl %xsp, CPU_esp(%cpu)
# TODO more of those
pop %rbx
pop %rbp
mov %tmp, %eax
ret

gadget interrupt
op %tmp
jmp jit_exit

gadget exit
movl $-1, %tmp
jmp jit_exit
19 changes: 19 additions & 0 deletions emu/gadgets-x86/gadgets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// register assignments
#define ip r8
#define tmp r9d
#define xsp r10d
#define cpu r11

.macro gadget name
.global gadget_\()\name
gadget_\()\name :
.endmacro
.macro endgadget
lea 8(%ip), %ip
jmp *-8(%ip)
.endmacro

.macro op reg
mov (%ip), \reg
lea 8(%ip), %ip
.endmacro
20 changes: 20 additions & 0 deletions emu/gadgets-x86/offsets.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "emu/cpu.h"

void cpu() {
OFFSET(CPU_eax, struct cpu_state, eax);
OFFSET(CPU_ebx, struct cpu_state, ebx);
OFFSET(CPU_ecx, struct cpu_state, ecx);
OFFSET(CPU_edx, struct cpu_state, edx);
OFFSET(CPU_esi, struct cpu_state, esi);
OFFSET(CPU_edi, struct cpu_state, edi);
OFFSET(CPU_ebp, struct cpu_state, ebp);
OFFSET(CPU_esp, struct cpu_state, esp);
OFFSET(CPU_ax, struct cpu_state, ax);
OFFSET(CPU_bx, struct cpu_state, bx);
OFFSET(CPU_cx, struct cpu_state, cx);
OFFSET(CPU_dx, struct cpu_state, dx);
OFFSET(CPU_si, struct cpu_state, si);
OFFSET(CPU_di, struct cpu_state, di);
OFFSET(CPU_bp, struct cpu_state, bp);
OFFSET(CPU_sp, struct cpu_state, sp);
}
7 changes: 7 additions & 0 deletions emu/gadgets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef EMU_GADGETS_H
#define EMU_GADGETS_H

void gadget_exit();
void gadget_interrupt();

#endif
157 changes: 157 additions & 0 deletions emu/gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
static void gen_step32(struct gen_state *state, addr_t ip, struct tlb *tlb);
static void gen_step16(struct gen_state *state, addr_t ip, struct tlb *tlb);

#define DECLARE_LOCALS \
dword_t addr_offset = 0;
#define RETURN(thing) (void) (thing)

#define TRACEIP() TRACE("%d %08x\t", current->pid, ip);

#define _READIMM(name, size) \
tlb_read(tlb, ip, &name, size/8); \
ip += size/8

#define READMODRM modrm_decode32(&ip, tlb, &modrm)
#define READADDR _READIMM(addr_offset, 32)
#define SEG_GS() UNDEFINED

#define UNDEFINED GG(interrupt, INT_UNDEFINED); return;

#define ADD(src, dst,z) UNDEFINED
#define OR(src, dst,z) UNDEFINED
#define ADC(src, dst,z) UNDEFINED
#define SBB(src, dst,z) UNDEFINED
#define AND(src, dst,z) UNDEFINED
#define SUB(src, dst,z) UNDEFINED
#define XOR(src, dst,z) UNDEFINED
#define CMP(src, dst,z) UNDEFINED
#define TEST(src, dst,z) UNDEFINED
#define NOT(val,z) UNDEFINED
#define NEG(val,z) UNDEFINED

#define INC(val,z) UNDEFINED
#define DEC(val,z) UNDEFINED

#define JMP(loc) UNDEFINED
#define JMP_REL(off) UNDEFINED
#define JCXZ_REL(off) UNDEFINED
#define J_REL(cc, off) UNDEFINED
#define CALL(loc) UNDEFINED
#define CALL_REL(off) UNDEFINED
#define SET(cc, dst) UNDEFINED
#define RET_NEAR_IMM(imm) UNDEFINED
#define RET_NEAR() UNDEFINED
#define INT(code) UNDEFINED

#define PUSHF() UNDEFINED
#define POPF() UNDEFINED
#define SAHF UNDEFINED
#define CLD UNDEFINED
#define STD UNDEFINED

#define MOV(src, dst,z) UNDEFINED
#define MOVZX(src, dst,zs,zd) UNDEFINED
#define MOVSX(src, dst,zs,zd) UNDEFINED
#define XCHG(src, dst,z) UNDEFINED
#define CMOV(cc, src, dst,z) UNDEFINED

#define POP(thing) UNDEFINED
#define PUSH(thing) UNDEFINED

#define MUL18(val) UNDEFINED
#define MUL1(val,z) UNDEFINED
#define IMUL1(val,z) UNDEFINED
#define MUL2(val, reg) UNDEFINED
#define IMUL2(val, reg,z) UNDEFINED
#define MUL3(imm, src, dst) UNDEFINED
#define IMUL3(imm, src, dst,z) UNDEFINED
#define DIV(reg, val, rem,z) UNDEFINED
#define IDIV(reg, val, rem,z) UNDEFINED

#define CVT UNDEFINED
#define CVTE UNDEFINED

#define ROL(count, val,z) UNDEFINED
#define ROR(count, val,z) UNDEFINED
#define SHL(count, val,z) UNDEFINED
#define SHR(count, val,z) UNDEFINED
#define SAR(count, val,z) UNDEFINED

#define SHLD(count, extra, dst,z) UNDEFINED
#define SHRD(count, extra, dst,z) UNDEFINED

#define BT(bit, val,z) UNDEFINED
#define BTC(bit, val,z) UNDEFINED
#define BTS(bit, val,z) UNDEFINED
#define BTR(bit, val,z) UNDEFINED
#define BSF(src, dst,z) UNDEFINED
#define BSR(src, dst,z) UNDEFINED

#define BSWAP(dst) UNDEFINED

#define SCAS(z) UNDEFINED
#define MOVS(z) UNDEFINED
#define LODS(z) UNDEFINED
#define STOS(z) UNDEFINED
#define CMPS(z) UNDEFINED
#define REP(op) UNDEFINED
#define REPZ(op) UNDEFINED
#define REPNZ(op) UNDEFINED

#define CMPXCHG(src, dst,z) UNDEFINED
#define XADD(src, dst,z) UNDEFINED

#define RDTSC UNDEFINED
#define CPUID() UNDEFINED

// sse
#define XORP(src, dst) UNDEFINED
#define PSRLQ(src, dst) UNDEFINED
#define PCMPEQD(src, dst) UNDEFINED
#define PADD(src, dst) UNDEFINED
#define PSUB(src, dst) UNDEFINED
#define MOVQ(src, dst) UNDEFINED
#define MOVD(src, dst) UNDEFINED
#define CVTTSD2SI(src, dst) UNDEFINED

// fpu
#define FLD() UNDEFINED
#define FILD(val,z) UNDEFINED
#define FLDM(val,z) UNDEFINED
#define FSTM(dst,z) UNDEFINED
#define FIST(dst,z) UNDEFINED
#define FXCH() UNDEFINED
#define FUCOM() UNDEFINED
#define FUCOMI() UNDEFINED
#define FST() UNDEFINED
#define FCHS() UNDEFINED
#define FABS() UNDEFINED
#define FLDC(what) UNDEFINED
#define FPREM() UNDEFINED
#define FSTSW(dst) UNDEFINED
#define FSTCW(dst) UNDEFINED
#define FLDCW(dst) UNDEFINED
#define FPOP UNDEFINED
#define FADD(src, dst) UNDEFINED
#define FIADD(val,z) UNDEFINED
#define FADDM(val,z) UNDEFINED
#define FSUB(src, dst) UNDEFINED
#define FSUBM(val,z) UNDEFINED
#define FISUB(val,z) UNDEFINED
#define FMUL(src, dst) UNDEFINED
#define FIMUL(val,z) UNDEFINED
#define FMULM(val,z) UNDEFINED
#define FDIV(src, dst) UNDEFINED
#define FIDIV(val,z) UNDEFINED
#define FDIVM(val,z) UNDEFINED

#define DECODER_RET static void
#define DECODER_NAME gen_step
#define DECODER_ARGS struct gen_state *state, addr_t ip, struct tlb *tlb
#define DECODER_PASS_ARGS state, ip, tlb
#define OP_SIZE 32
#include "emu/decode.h"
#undef OP_SIZE
#define OP_SIZE 16
#include "emu/decode.h"
#undef OP_SIZE
13 changes: 10 additions & 3 deletions emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"

#define DECLARE_LOCALS \
dword_t addr_offset = 0; \
dword_t saved_ip = cpu->eip; \
struct modrm modrm; \
struct regptr modrm_regptr, modrm_base; \
dword_t addr = 0; \
\
Expand All @@ -18,8 +18,7 @@
\
extFloat80_t ftmp;

#define FINISH \
return -1 // everything is ok.
#define RETURN(thing) return (thing)

#define UNDEFINED { cpu->eip = saved_ip; return INT_UNDEFINED; }

Expand All @@ -31,11 +30,16 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
cpu->eip = saved_ip; \
return INT_GPF; \
}
#define READADDR READIMM_(addr_offset, 32); addr += addr_offset

#define _READIMM(name,size) \
name = mem_read(cpu->eip, size); \
cpu->eip += size/8

#define TRACEIP() TRACE("%d %08x\t", current->pid, cpu->eip);

#define SEG_GS() addr += cpu->tls_ptr

// this is a completely insane way to turn empty into OP_SIZE and any other size into itself
#define sz(x) sz_##x
#define sz_ OP_SIZE
Expand Down Expand Up @@ -590,6 +594,9 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
cpu->eax = imm & 0xffffffff; \
cpu->edx = imm >> 32

#define CPUID() \
do_cpuid(&cpu->eax, &cpu->ebx, &cpu->ecx, &cpu->edx)

#include "emu/interp/sse.h"
#include "emu/interp/fpu.h"

Expand Down
Loading

0 comments on commit 498c17b

Please sign in to comment.