From bcb97799d06eeb0f6d994acc8174c9b6e3d23149 Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Mon, 30 Dec 2024 15:05:00 +0100 Subject: [PATCH] Use wrapper functions for the memory handlers that are called at runtime by the jitted code Data accesses from the jitted code are never privileged --- lib86cpu/core/emitter/emitter_common.h | 24 ++++++------- lib86cpu/core/emitter/x64/jit.cpp | 47 ++++++++++++-------------- lib86cpu/core/emitter/x64/jit.h | 4 +-- lib86cpu/core/memory_management.cpp | 37 ++++++++++++++++++-- lib86cpu/core/memory_management.h | 6 ++-- 5 files changed, 73 insertions(+), 45 deletions(-) diff --git a/lib86cpu/core/emitter/emitter_common.h b/lib86cpu/core/emitter/emitter_common.h index f48c6f9..247a484 100644 --- a/lib86cpu/core/emitter/emitter_common.h +++ b/lib86cpu/core/emitter/emitter_common.h @@ -152,18 +152,18 @@ inline constexpr auto all_callable_funcs = std::make_tuple( cpu_raise_exception<3, false>, cpu_timer_helper, cpu_do_int, - mem_read_helper, - mem_read_helper, - mem_read_helper, - mem_read_helper, - mem_read_helper, - mem_read_helper, - mem_write_helper, - mem_write_helper, - mem_write_helper, - mem_write_helper, - mem_write_helper, - mem_write_helper, + mem_read_jit_helper, + mem_read_jit_helper, + mem_read_jit_helper, + mem_read_jit_helper, + mem_read_jit_helper, + mem_read_jit_helper, + mem_write_jit_helper, + mem_write_jit_helper, + mem_write_jit_helper, + mem_write_jit_helper, + mem_write_jit_helper, + mem_write_jit_helper, io_read_helper, io_read_helper, io_read_helper, diff --git a/lib86cpu/core/emitter/x64/jit.cpp b/lib86cpu/core/emitter/x64/jit.cpp index cdd4502..5e9e40e 100644 --- a/lib86cpu/core/emitter/x64/jit.cpp +++ b/lib86cpu/core/emitter/x64/jit.cpp @@ -470,13 +470,13 @@ static_assert((LOCAL_VARS_off(0) & 15) == 0); // must be 16 byte aligned so that #define ST_SEG_BASE(seg_offset, val) MOV(MEMD32(RCX, seg_offset + seg_base_offset), val) #define ST_SEG_LIMIT(seg_offset, val) MOV(MEMD32(RCX, seg_offset + seg_limit_offset), val) -#define LD_MEM() load_mem(m_cpu->size_mode, 0) -#define LD_MEMs(size) load_mem(size, 0) -#define LD_MEM128() load_mem(SIZE128, 0) -#define ST_MEM(val) store_mem(val, m_cpu->size_mode, 0) -#define ST_MEMs(val, size) store_mem(val, size, 0) -#define ST_MEM128(val) store_mem(val, SIZE128, 0) -#define ST_MEMv(val) store_mem(val, m_cpu->size_mode, 0) +#define LD_MEM() load_mem(m_cpu->size_mode) +#define LD_MEMs(size) load_mem(size) +#define LD_MEM128() load_mem(SIZE128) +#define ST_MEM(val) store_mem(val, m_cpu->size_mode) +#define ST_MEMs(val, size) store_mem(val, size) +#define ST_MEM128(val) store_mem(val, SIZE128) +#define ST_MEMv(val) store_mem(val, m_cpu->size_mode) #define LD_IO() load_io(m_cpu->size_mode) #define ST_IO() store_io(m_cpu->size_mode) @@ -1722,7 +1722,7 @@ lc86_jit::ld_pf(x86::Gp dst, x86::Gp res, x86::Gp aux) } void -lc86_jit::load_mem(uint8_t size, uint8_t is_priv) +lc86_jit::load_mem(uint8_t size) { // RCX: cpu_ctx, EDX: addr // for SIZE128/80 -> RCX: ptr to stack-allocated uint128/80_t, RDX: cpu_ctx, R8: addr @@ -1733,37 +1733,33 @@ lc86_jit::load_mem(uint8_t size, uint8_t is_priv) LEA(RCX, MEMD64(RSP, LOCAL_VARS_off(0))); MOV(R8D, EDX); MOV(RDX, &m_cpu->cpu_ctx); - MOV(R9B, is_priv); - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; case SIZE80: LEA(RCX, MEMD64(RSP, LOCAL_VARS_off(0))); MOV(R8D, EDX); MOV(RDX, &m_cpu->cpu_ctx); - MOV(R9B, is_priv); - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; default: - MOV(R8B, is_priv); - switch (size) { case SIZE64: - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; case SIZE32: - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; case SIZE16: - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; case SIZE8: - CALL_F(&mem_read_helper); + CALL_F(&mem_read_jit_helper); break; default: @@ -1773,7 +1769,7 @@ lc86_jit::load_mem(uint8_t size, uint8_t is_priv) } template -void lc86_jit::store_mem(T val, uint8_t size, uint8_t is_priv) +void lc86_jit::store_mem(T val, uint8_t size) { // RCX: cpu_ctx, EDX: addr, R8/D/W/B or imm: val @@ -1783,32 +1779,31 @@ void lc86_jit::store_mem(T val, uint8_t size, uint8_t is_priv) else { MOV(R8, val); } - MOV(R9B, is_priv); switch (size) { case SIZE128: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; case SIZE80: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; case SIZE64: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; case SIZE32: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; case SIZE16: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; case SIZE8: - CALL_F((&mem_write_helper)); + CALL_F((&mem_write_jit_helper)); break; default: diff --git a/lib86cpu/core/emitter/x64/jit.h b/lib86cpu/core/emitter/x64/jit.h index 2cb1e51..ed11aae 100644 --- a/lib86cpu/core/emitter/x64/jit.h +++ b/lib86cpu/core/emitter/x64/jit.h @@ -245,9 +245,9 @@ class lc86_jit : public Target { void ld_of(x86::Gp dst, x86::Gp aux); void ld_sf(x86::Gp res_dst, x86::Gp aux); void ld_pf(x86::Gp dst, x86::Gp res, x86::Gp aux); - void load_mem(uint8_t size, uint8_t is_priv); + void load_mem(uint8_t size); template - void store_mem(T val, uint8_t size, uint8_t is_priv); + void store_mem(T val, uint8_t size); void load_io(uint8_t size_mode); void store_io(uint8_t size_mode); template diff --git a/lib86cpu/core/memory_management.cpp b/lib86cpu/core/memory_management.cpp index 3197c72..f378f02 100644 --- a/lib86cpu/core/memory_management.cpp +++ b/lib86cpu/core/memory_management.cpp @@ -541,7 +541,6 @@ ram_fetch(cpu_t *cpu, disas_ctx_t *disas_ctx, uint8_t *buffer) } } -// memory read helper invoked by the jitted code template T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv) { @@ -608,7 +607,6 @@ T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv) return mem_read_slow(cpu_ctx->cpu, addr, is_priv); } -// memory write helper invoked by the jitted code template void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv) { @@ -703,6 +701,20 @@ void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv) } } +// memory read helper invoked by the jitted code +template +T mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr) +{ + return mem_read_helper(cpu_ctx, addr, 0); +} + +// memory write helper invoked by the jitted code +template +void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val) +{ + mem_write_helper(cpu_ctx, addr, val, 0); +} + // io read helper invoked by the jitted code template T io_read_helper(cpu_ctx_t *cpu_ctx, port_t port) @@ -718,7 +730,7 @@ void io_write_helper(cpu_ctx_t *cpu_ctx, port_t port, T val) cpu_check_io_watchpoints(cpu_ctx->cpu, port, sizeof(T), DR7_TYPE_IO_RW); io_write(cpu_ctx->cpu, port, val); } - +#if 0 template JIT_API uint8_t mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv); template JIT_API uint16_t mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv); template JIT_API uint32_t mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv); @@ -737,6 +749,25 @@ template JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_ template JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val, uint8_t is_priv); template JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val, uint8_t is_priv); template JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint128_t val, uint8_t is_priv); +#endif +template JIT_API uint8_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API uint16_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API uint32_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API uint64_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API uint80_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API uint128_t mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint16_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint32_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint128_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint16_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint32_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint128_t val); template JIT_API uint8_t io_read_helper(cpu_ctx_t *cpu_ctx, port_t port); template JIT_API uint16_t io_read_helper(cpu_ctx_t *cpu_ctx, port_t port); diff --git a/lib86cpu/core/memory_management.h b/lib86cpu/core/memory_management.h index b4eb82e..7c5cb46 100644 --- a/lib86cpu/core/memory_management.h +++ b/lib86cpu/core/memory_management.h @@ -32,8 +32,10 @@ template T ram_read(cpu_t *cpu, void *ram_ptr); template void ram_write(cpu_t *cpu, void *ram_ptr, T value); void ram_fetch(cpu_t *cpu, disas_ctx_t *disas_ctx, uint8_t *buffer); uint64_t as_ram_dispatch_read(cpu_t *cpu, addr_t addr, uint64_t size, const memory_region_t *region, uint8_t *buffer); -template JIT_API T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv); -template JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv); +template T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv); +template void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv); +template JIT_API T mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr); +template JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val); template JIT_API T io_read_helper(cpu_ctx_t * cpu_ctx, port_t port); template JIT_API void io_write_helper(cpu_ctx_t * cpu_ctx, port_t port, T val);