Skip to content

Commit

Permalink
Use wrapper functions for the memory handlers that are called at runt…
Browse files Browse the repository at this point in the history
…ime by the jitted code

Data accesses from the jitted code are never privileged
  • Loading branch information
ergo720 committed Dec 30, 2024
1 parent 36ef718 commit bcb9779
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 45 deletions.
24 changes: 12 additions & 12 deletions lib86cpu/core/emitter/emitter_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint128_t>,
mem_read_helper<uint80_t>,
mem_read_helper<uint64_t>,
mem_read_helper<uint32_t>,
mem_read_helper<uint16_t>,
mem_read_helper<uint8_t>,
mem_write_helper<uint128_t>,
mem_write_helper<uint80_t>,
mem_write_helper<uint64_t>,
mem_write_helper<uint32_t>,
mem_write_helper<uint16_t>,
mem_write_helper<uint8_t>,
mem_read_jit_helper<uint128_t>,
mem_read_jit_helper<uint80_t>,
mem_read_jit_helper<uint64_t>,
mem_read_jit_helper<uint32_t>,
mem_read_jit_helper<uint16_t>,
mem_read_jit_helper<uint8_t>,
mem_write_jit_helper<uint128_t>,
mem_write_jit_helper<uint80_t>,
mem_write_jit_helper<uint64_t>,
mem_write_jit_helper<uint32_t>,
mem_write_jit_helper<uint16_t>,
mem_write_jit_helper<uint8_t>,
io_read_helper<uint32_t>,
io_read_helper<uint16_t>,
io_read_helper<uint8_t>,
Expand Down
47 changes: 21 additions & 26 deletions lib86cpu/core/emitter/x64/jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<decltype(val), true>(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<decltype(val), true>(val, m_cpu->size_mode)

#define LD_IO() load_io(m_cpu->size_mode)
#define ST_IO() store_io(m_cpu->size_mode)
Expand Down Expand Up @@ -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
Expand All @@ -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<uint128_t>);
CALL_F(&mem_read_jit_helper<uint128_t>);
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<uint80_t>);
CALL_F(&mem_read_jit_helper<uint80_t>);
break;

default:
MOV(R8B, is_priv);

switch (size)
{
case SIZE64:
CALL_F(&mem_read_helper<uint64_t>);
CALL_F(&mem_read_jit_helper<uint64_t>);
break;

case SIZE32:
CALL_F(&mem_read_helper<uint32_t>);
CALL_F(&mem_read_jit_helper<uint32_t>);
break;

case SIZE16:
CALL_F(&mem_read_helper<uint16_t>);
CALL_F(&mem_read_jit_helper<uint16_t>);
break;

case SIZE8:
CALL_F(&mem_read_helper<uint8_t>);
CALL_F(&mem_read_jit_helper<uint8_t>);
break;

default:
Expand All @@ -1773,7 +1769,7 @@ lc86_jit::load_mem(uint8_t size, uint8_t is_priv)
}

template<typename T, bool dont_write>
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

Expand All @@ -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<uint128_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint128_t, dont_write>));
break;

case SIZE80:
CALL_F((&mem_write_helper<uint80_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint80_t, dont_write>));
break;

case SIZE64:
CALL_F((&mem_write_helper<uint64_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint64_t, dont_write>));
break;

case SIZE32:
CALL_F((&mem_write_helper<uint32_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint32_t, dont_write>));
break;

case SIZE16:
CALL_F((&mem_write_helper<uint16_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint16_t, dont_write>));
break;

case SIZE8:
CALL_F((&mem_write_helper<uint8_t, dont_write>));
CALL_F((&mem_write_jit_helper<uint8_t, dont_write>));
break;

default:
Expand Down
4 changes: 2 additions & 2 deletions lib86cpu/core/emitter/x64/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T, bool dont_write = false>
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<typename T>
Expand Down
37 changes: 34 additions & 3 deletions lib86cpu/core/memory_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T>
T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv)
{
Expand Down Expand Up @@ -608,7 +607,6 @@ T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv)
return mem_read_slow<T>(cpu_ctx->cpu, addr, is_priv);
}

// memory write helper invoked by the jitted code
template<typename T, bool dont_write>
void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv)
{
Expand Down Expand Up @@ -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<typename T>
T mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr)
{
return mem_read_helper<T>(cpu_ctx, addr, 0);
}

// memory write helper invoked by the jitted code
template<typename T, bool dont_write>
void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val)
{
mem_write_helper<T, dont_write>(cpu_ctx, addr, val, 0);
}

// io read helper invoked by the jitted code
template<typename T>
T io_read_helper(cpu_ctx_t *cpu_ctx, port_t port)
Expand All @@ -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<T>(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);
Expand All @@ -737,6 +749,25 @@ template JIT_API void mem_write_helper<uint32_t, true>(cpu_ctx_t *cpu_ctx, addr_
template JIT_API void mem_write_helper<uint64_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val, uint8_t is_priv);
template JIT_API void mem_write_helper<uint80_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val, uint8_t is_priv);
template JIT_API void mem_write_helper<uint128_t, true>(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<uint8_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t val);
template JIT_API void mem_write_jit_helper<uint16_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint16_t val);
template JIT_API void mem_write_jit_helper<uint32_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint32_t val);
template JIT_API void mem_write_jit_helper<uint64_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val);
template JIT_API void mem_write_jit_helper<uint80_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val);
template JIT_API void mem_write_jit_helper<uint128_t, false>(cpu_ctx_t *cpu_ctx, addr_t addr, uint128_t val);
template JIT_API void mem_write_jit_helper<uint8_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t val);
template JIT_API void mem_write_jit_helper<uint16_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint16_t val);
template JIT_API void mem_write_jit_helper<uint32_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint32_t val);
template JIT_API void mem_write_jit_helper<uint64_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint64_t val);
template JIT_API void mem_write_jit_helper<uint80_t, true>(cpu_ctx_t *cpu_ctx, addr_t addr, uint80_t val);
template JIT_API void mem_write_jit_helper<uint128_t, true>(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);
Expand Down
6 changes: 4 additions & 2 deletions lib86cpu/core/memory_management.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ template<typename T> T ram_read(cpu_t *cpu, void *ram_ptr);
template<typename T> 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<addr_t> *region, uint8_t *buffer);
template<typename T> JIT_API T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv);
template<typename T, bool dont_write = false> JIT_API void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv);
template<typename T> T mem_read_helper(cpu_ctx_t *cpu_ctx, addr_t addr, uint8_t is_priv);
template<typename T, bool dont_write = false> void mem_write_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val, uint8_t is_priv);
template<typename T> JIT_API T mem_read_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr);
template<typename T, bool dont_write = false> JIT_API void mem_write_jit_helper(cpu_ctx_t *cpu_ctx, addr_t addr, T val);
template<typename T> JIT_API T io_read_helper(cpu_ctx_t * cpu_ctx, port_t port);
template<typename T> JIT_API void io_write_helper(cpu_ctx_t * cpu_ctx, port_t port, T val);

Expand Down

0 comments on commit bcb9779

Please sign in to comment.