From f935469658672173ce6ad1bebbb9c5e89d7475cf Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Mon, 28 Dec 2015 15:19:30 +0800 Subject: [PATCH] mips: handle memory redirect for all APIs. this fixes issue #347 --- qemu/softmmu_template.h | 2 +- uc.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h index 3b2a6295..e3100fcd 100644 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -182,7 +182,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, struct uc_struct *uc = env->uc; MemoryRegion *mr = memory_mapping(uc, addr); - // memory can be unmapped while reading or fetching + // memory might be still unmapped while reading or fetching if (mr == NULL) { #if defined(SOFTMMU_CODE_ACCESS) error_code = UC_ERR_FETCH_UNMAPPED; diff --git a/uc.c b/uc.c index a2944630..63395da9 100644 --- a/uc.c +++ b/uc.c @@ -343,13 +343,16 @@ static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size) UNICORN_EXPORT uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) { + size_t count = 0, len; uint8_t *bytes = _bytes; + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + if (!check_mem_area(uc, address, size)) return UC_ERR_READ_UNMAPPED; - size_t count = 0, len; - // memory area can overlap adjacent memory blocks while(count < size) { MemoryRegion *mr = memory_mapping(uc, address); @@ -373,13 +376,16 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) UNICORN_EXPORT uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, size_t size) { + size_t count = 0, len; const uint8_t *bytes = _bytes; + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + if (!check_mem_area(uc, address, size)) return UC_ERR_WRITE_UNMAPPED; - size_t count = 0, len; - // memory area can overlap adjacent memory blocks while(count < size) { MemoryRegion *mr = memory_mapping(uc, address); @@ -617,6 +623,10 @@ static uc_err mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t per UNICORN_EXPORT uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) { + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + return mem_map(uc, address, size, perms, uc->memory_map(uc, address, size, perms)); } @@ -626,6 +636,10 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t per if (ptr == NULL) return UC_ERR_ARG; + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + return mem_map(uc, address, size, UC_PROT_ALL, uc->memory_map_ptr(uc, address, size, perms, ptr)); } @@ -769,6 +783,10 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, uint3 if ((perms & ~UC_PROT_ALL) != 0) return UC_ERR_ARG; + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + // check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) return UC_ERR_NOMEM; @@ -812,6 +830,10 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) if ((size & uc->target_page_align) != 0) return UC_ERR_MAP; + if (uc->mem_redirect) { + address = uc->mem_redirect(address); + } + // check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) return UC_ERR_NOMEM;