Remove MMU hacks

Unicorn has included some ugly hacks to provide a envirement where vaddr == paddr.
These hacks where to use the full 64 bit mappings on x86 without init the mmu
and some memory redirect for MIPS.

The UC_TLB_CPU mode defaults to vaddr == paddr, therfor these hacks aren't
required anymore.
This commit is contained in:
Takacs, Philipp 2023-02-13 15:07:40 +01:00
parent e25419bb2d
commit e96ac42b2e
17 changed files with 10 additions and 83 deletions

View File

@ -119,9 +119,6 @@ typedef MemoryRegion *(*uc_memory_map_io_t)(struct uc_struct *uc,
// which interrupt should make emulation stop? // which interrupt should make emulation stop?
typedef bool (*uc_args_int_t)(struct uc_struct *uc, int intno); typedef bool (*uc_args_int_t)(struct uc_struct *uc, int intno);
// some architecture redirect virtual memory to physical memory like Mips
typedef uint64_t (*uc_mem_redirect_t)(uint64_t address);
// validate if Unicorn supports hooking a given instruction // validate if Unicorn supports hooking a given instruction
typedef bool (*uc_insn_hook_validate)(uint32_t insn_enum); typedef bool (*uc_insn_hook_validate)(uint32_t insn_enum);
@ -287,7 +284,6 @@ struct uc_struct {
uc_args_uc_ram_size_ptr_t memory_map_ptr; uc_args_uc_ram_size_ptr_t memory_map_ptr;
uc_mem_unmap_t memory_unmap; uc_mem_unmap_t memory_unmap;
uc_readonly_mem_t readonly_mem; uc_readonly_mem_t readonly_mem;
uc_mem_redirect_t mem_redirect;
uc_cpus_init cpus_init; uc_cpus_init cpus_init;
uc_target_page_init target_page; uc_target_page_init target_page;
uc_softfloat_initialize softfloat_initialize; uc_softfloat_initialize softfloat_initialize;

View File

@ -2080,7 +2080,6 @@ void arm_cpu_class_init(struct uc_struct *uc, CPUClass *oc)
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug; cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
cc->asidx_from_attrs = arm_asidx_from_attrs; cc->asidx_from_attrs = arm_asidx_from_attrs;
cc->tcg_initialize = arm_translate_init; cc->tcg_initialize = arm_translate_init;
cc->tlb_fill = arm_cpu_tlb_fill;
cc->tlb_fill_cpu = arm_cpu_tlb_fill; cc->tlb_fill_cpu = arm_cpu_tlb_fill;
cc->debug_excp_handler = arm_debug_excp_handler; cc->debug_excp_handler = arm_debug_excp_handler;
cc->do_unaligned_access = arm_cpu_do_unaligned_access; cc->do_unaligned_access = arm_cpu_do_unaligned_access;

View File

@ -5066,7 +5066,6 @@ static void x86_cpu_common_class_init(struct uc_struct *uc, CPUClass *oc, void *
cc->cpu_exec_enter = x86_cpu_exec_enter; cc->cpu_exec_enter = x86_cpu_exec_enter;
cc->cpu_exec_exit = x86_cpu_exec_exit; cc->cpu_exec_exit = x86_cpu_exec_exit;
cc->tcg_initialize = tcg_x86_init; cc->tcg_initialize = tcg_x86_init;
cc->tlb_fill = x86_cpu_tlb_fill;
cc->tlb_fill_cpu = x86_cpu_tlb_fill; cc->tlb_fill_cpu = x86_cpu_tlb_fill;
} }

View File

@ -635,12 +635,7 @@ do_check_protect_pse36:
/* align to page_size */ /* align to page_size */
pte &= PG_ADDRESS_MASK & ~(page_size - 1); pte &= PG_ADDRESS_MASK & ~(page_size - 1);
page_offset = addr & (page_size - 1); page_offset = addr & (page_size - 1);
/* HACK allow full 64 bit mapping in u64 without paging */ paddr = get_hphys(cs, pte + page_offset, is_write1, &prot);
if (env->cr[0] & CR0_PG_MASK) {
paddr = get_hphys(cs, pte + page_offset, is_write1, &prot);
} else {
paddr = addr;
}
/* Even if 4MB pages, we map only one 4KB page in the cache to /* Even if 4MB pages, we map only one 4KB page in the cache to
avoid filling it too fast */ avoid filling it too fast */

View File

@ -231,7 +231,6 @@ static void m68k_cpu_class_init(CPUClass *c)
cc->do_interrupt = m68k_cpu_do_interrupt; cc->do_interrupt = m68k_cpu_do_interrupt;
cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt; cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
cc->set_pc = m68k_cpu_set_pc; cc->set_pc = m68k_cpu_set_pc;
cc->tlb_fill = m68k_cpu_tlb_fill;
cc->tlb_fill_cpu = m68k_cpu_tlb_fill; cc->tlb_fill_cpu = m68k_cpu_tlb_fill;
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
cc->tcg_initialize = m68k_tcg_init; cc->tcg_initialize = m68k_tcg_init;

View File

@ -147,7 +147,6 @@ static void mips_cpu_class_init(CPUClass *c)
cc->do_unaligned_access = mips_cpu_do_unaligned_access; cc->do_unaligned_access = mips_cpu_do_unaligned_access;
cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
cc->tcg_initialize = mips_tcg_init; cc->tcg_initialize = mips_tcg_init;
cc->tlb_fill = mips_cpu_tlb_fill;
cc->tlb_fill_cpu = mips_cpu_tlb_fill; cc->tlb_fill_cpu = mips_cpu_tlb_fill;
} }

View File

@ -17,21 +17,6 @@ typedef uint32_t mipsreg_t;
MIPSCPU *cpu_mips_init(struct uc_struct *uc); MIPSCPU *cpu_mips_init(struct uc_struct *uc);
static uint64_t mips_mem_redirect(uint64_t address)
{
// kseg0 range masks off high address bit
if (address >= 0x80000000 && address <= 0x9fffffff)
return address & 0x7fffffff;
// kseg1 range masks off top 3 address bits
if (address >= 0xa0000000 && address <= 0xbfffffff) {
return address & 0x1fffffff;
}
// no redirect
return address;
}
static void mips_set_pc(struct uc_struct *uc, uint64_t address) static void mips_set_pc(struct uc_struct *uc, uint64_t address)
{ {
((CPUMIPSState *)uc->cpu->env_ptr)->active_tc.PC = address; ((CPUMIPSState *)uc->cpu->env_ptr)->active_tc.PC = address;
@ -272,7 +257,6 @@ void mipsel_uc_init(struct uc_struct *uc)
uc->release = mips_release; uc->release = mips_release;
uc->set_pc = mips_set_pc; uc->set_pc = mips_set_pc;
uc->get_pc = mips_get_pc; uc->get_pc = mips_get_pc;
uc->mem_redirect = mips_mem_redirect;
uc->cpus_init = mips_cpus_init; uc->cpus_init = mips_cpus_init;
uc->cpu_context_size = offsetof(CPUMIPSState, end_reset_fields); uc->cpu_context_size = offsetof(CPUMIPSState, end_reset_fields);
uc_common_init(uc); uc_common_init(uc);

View File

@ -10253,7 +10253,6 @@ static void ppc_cpu_class_init(struct uc_struct *uc, CPUClass *oc)
cc->do_unaligned_access = ppc_cpu_do_unaligned_access; cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
cc->tcg_initialize = ppc_translate_init; cc->tcg_initialize = ppc_translate_init;
cc->tlb_fill = ppc_cpu_tlb_fill;
cc->tlb_fill_cpu = ppc_cpu_tlb_fill; cc->tlb_fill_cpu = ppc_cpu_tlb_fill;
cc->cpu_exec_enter = ppc_cpu_exec_enter; cc->cpu_exec_enter = ppc_cpu_exec_enter;
cc->cpu_exec_exit = ppc_cpu_exec_exit; cc->cpu_exec_exit = ppc_cpu_exec_exit;

View File

@ -77,21 +77,6 @@ static inline int uc_ppc_store_msr(CPUPPCState *env, target_ulong value,
return 0; return 0;
} }
static uint64_t ppc_mem_redirect(uint64_t address)
{
/* // kseg0 range masks off high address bit
if (address >= 0x80000000 && address <= 0x9fffffff)
return address & 0x7fffffff;
// kseg1 range masks off top 3 address bits
if (address >= 0xa0000000 && address <= 0xbfffffff) {
return address & 0x1fffffff;
}*/
// no redirect
return address;
}
static void ppc_set_pc(struct uc_struct *uc, uint64_t address) static void ppc_set_pc(struct uc_struct *uc, uint64_t address)
{ {
((CPUPPCState *)uc->cpu->env_ptr)->nip = address; ((CPUPPCState *)uc->cpu->env_ptr)->nip = address;
@ -435,7 +420,6 @@ void ppc_uc_init(struct uc_struct *uc)
uc->release = ppc_release; uc->release = ppc_release;
uc->set_pc = ppc_set_pc; uc->set_pc = ppc_set_pc;
uc->get_pc = ppc_get_pc; uc->get_pc = ppc_get_pc;
uc->mem_redirect = ppc_mem_redirect;
uc->cpus_init = ppc_cpus_init; uc->cpus_init = ppc_cpus_init;
uc->cpu_context_size = offsetof(CPUPPCState, uc); uc->cpu_context_size = offsetof(CPUPPCState, uc);
uc_common_init(uc); uc_common_init(uc);

View File

@ -307,7 +307,6 @@ static void riscv_cpu_class_init(struct uc_struct *uc, CPUClass *c, void *data)
cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb; cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
cc->do_unaligned_access = riscv_cpu_do_unaligned_access; cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
cc->tcg_initialize = riscv_translate_init; cc->tcg_initialize = riscv_translate_init;
cc->tlb_fill = riscv_cpu_tlb_fill;
cc->tlb_fill_cpu = riscv_cpu_tlb_fill; cc->tlb_fill_cpu = riscv_cpu_tlb_fill;
} }

View File

@ -233,7 +233,6 @@ static void s390_cpu_class_init(struct uc_struct *uc, CPUClass *oc)
cc->debug_excp_handler = s390x_cpu_debug_excp_handler; cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
cc->do_unaligned_access = s390x_cpu_do_unaligned_access; cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
cc->tcg_initialize = s390x_translate_init; cc->tcg_initialize = s390x_translate_init;
cc->tlb_fill = s390_cpu_tlb_fill;
cc->tlb_fill_cpu = s390_cpu_tlb_fill; cc->tlb_fill_cpu = s390_cpu_tlb_fill;
// s390_cpu_model_class_register_props(oc); // s390_cpu_model_class_register_props(oc);

View File

@ -504,7 +504,6 @@ static void sparc_cpu_class_init(struct uc_struct *uc, CPUClass *oc)
cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt; cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
cc->set_pc = sparc_cpu_set_pc; cc->set_pc = sparc_cpu_set_pc;
cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
cc->tlb_fill = sparc_cpu_tlb_fill;
cc->tlb_fill_cpu = sparc_cpu_tlb_fill; cc->tlb_fill_cpu = sparc_cpu_tlb_fill;
cc->do_unaligned_access = sparc_cpu_do_unaligned_access; cc->do_unaligned_access = sparc_cpu_do_unaligned_access;
cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;

View File

@ -137,7 +137,6 @@ static void tricore_cpu_class_init(CPUClass *c)
cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb; cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug; cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug;
cc->tlb_fill = tricore_cpu_tlb_fill;
cc->tlb_fill_cpu = tricore_cpu_tlb_fill; cc->tlb_fill_cpu = tricore_cpu_tlb_fill;
cc->tcg_initialize = tricore_tcg_init; cc->tcg_initialize = tricore_tcg_init;
} }

View File

@ -416,6 +416,7 @@ static void test_arm64_mmu(void)
TEST_CHECK(data != NULL); TEST_CHECK(data != NULL);
OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
OK(uc_mem_map(uc, 0, 0x2000, UC_PROT_ALL)); OK(uc_mem_map(uc, 0, 0x2000, UC_PROT_ALL));
OK(uc_mem_write(uc, 0, code, sizeof(code) - 1)); OK(uc_mem_write(uc, 0, code, sizeof(code) - 1));

View File

@ -689,6 +689,7 @@ static void test_riscv_mmu(void)
char code_s[] = "\xb7\x42\x41\x41" "\x9b\x82\x12\x14" "\x37\x63\x01\x00" "\x23\x20\x53\x00" "\x13\x00\x00\x00"; char code_s[] = "\xb7\x42\x41\x41" "\x9b\x82\x12\x14" "\x37\x63\x01\x00" "\x23\x20\x53\x00" "\x13\x00\x00\x00";
OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc)); OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc));
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_riscv_mmu_hook_code, NULL, 1, 0)); OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_riscv_mmu_hook_code, NULL, 1, 0));
OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL));
OK(uc_mem_map(uc, code_address, 0x1000, UC_PROT_ALL)); OK(uc_mem_map(uc, code_address, 0x1000, UC_PROT_ALL));

View File

@ -1090,6 +1090,7 @@ static void test_x86_correct_address_in_long_jump_hook(void)
uc_hook hook; uc_hook hook;
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1); uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1);
OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL));
OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_UNMAPPED, OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_UNMAPPED,
test_x86_correct_address_in_long_jump_hook_callback, NULL, 1, test_x86_correct_address_in_long_jump_hook_callback, NULL, 1,
0)); 0));
@ -1348,6 +1349,7 @@ static void test_x86_mmu(void)
char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05";
OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc)); OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc));
OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU));
OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL)); OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL));
OK(uc_context_alloc(uc, &context)); OK(uc_context_alloc(uc, &context));

37
uc.c
View File

@ -230,6 +230,11 @@ static uc_err uc_init(uc_engine *uc)
return UC_ERR_RESOURCE; return UC_ERR_RESOURCE;
} }
// init tlb function
if (!uc->cpu->cc->tlb_fill) {
uc->set_tlb(uc, UC_TLB_CPU);
}
// init fpu softfloat // init fpu softfloat
uc->softfloat_initialize(); uc->softfloat_initialize();
@ -577,10 +582,6 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
if (size > INT_MAX) if (size > INT_MAX)
return UC_ERR_ARG; return UC_ERR_ARG;
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
if (!check_mem_area(uc, address, size)) { if (!check_mem_area(uc, address, size)) {
return UC_ERR_READ_UNMAPPED; return UC_ERR_READ_UNMAPPED;
} }
@ -622,10 +623,6 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes,
if (size > INT_MAX) if (size > INT_MAX)
return UC_ERR_ARG; return UC_ERR_ARG;
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
if (!check_mem_area(uc, address, size)) { if (!check_mem_area(uc, address, size)) {
return UC_ERR_WRITE_UNMAPPED; return UC_ERR_WRITE_UNMAPPED;
} }
@ -1039,10 +1036,6 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms)
UC_INIT(uc); UC_INIT(uc);
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
res = mem_map_check(uc, address, size, perms); res = mem_map_check(uc, address, size, perms);
if (res) { if (res) {
return res; return res;
@ -1063,10 +1056,6 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size,
return UC_ERR_ARG; return UC_ERR_ARG;
} }
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
res = mem_map_check(uc, address, size, perms); res = mem_map_check(uc, address, size, perms);
if (res) { if (res) {
return res; return res;
@ -1084,10 +1073,6 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size,
UC_INIT(uc); UC_INIT(uc);
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
res = mem_map_check(uc, address, size, UC_PROT_ALL); res = mem_map_check(uc, address, size, UC_PROT_ALL);
if (res) if (res)
return res; return res;
@ -1387,10 +1372,6 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size,
return UC_ERR_ARG; return UC_ERR_ARG;
} }
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
// check that user's entire requested block is mapped // check that user's entire requested block is mapped
if (!check_mem_area(uc, address, size)) { if (!check_mem_area(uc, address, size)) {
return UC_ERR_NOMEM; return UC_ERR_NOMEM;
@ -1467,10 +1448,6 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size)
return UC_ERR_ARG; return UC_ERR_ARG;
} }
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
// check that user's entire requested block is mapped // check that user's entire requested block is mapped
if (!check_mem_area(uc, address, size)) { if (!check_mem_area(uc, address, size)) {
return UC_ERR_NOMEM; return UC_ERR_NOMEM;
@ -1515,10 +1492,6 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address)
return NULL; return NULL;
} }
if (uc->mem_redirect) {
address = uc->mem_redirect(address);
}
// try with the cache index first // try with the cache index first
i = uc->mapped_block_cache_index; i = uc->mapped_block_cache_index;