From 03e8b28d71dd23bca69ce1a55da7dadd18216e6b Mon Sep 17 00:00:00 2001 From: Chris Eagle Date: Tue, 25 Aug 2015 21:52:18 -0700 Subject: [PATCH] First cut at cleaning up uc_mem_map, eliminate map_begin and map_end, move tracking inside uc struct --- include/uc_priv.h | 10 +++++++++- include/unicorn/unicorn.h | 6 ++++++ qemu/softmmu_template.h | 8 ++++---- uc.c | 27 +++++++++++++++------------ 4 files changed, 34 insertions(+), 17 deletions(-) mode change 100644 => 100755 include/uc_priv.h mode change 100644 => 100755 include/unicorn/unicorn.h mode change 100644 => 100755 qemu/softmmu_template.h mode change 100644 => 100755 uc.c diff --git a/include/uc_priv.h b/include/uc_priv.h old mode 100644 new mode 100755 index 2703627c..02dd32f3 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -15,6 +15,12 @@ QTAILQ_HEAD(CPUTailQ, CPUState); +typedef struct MemoryBlock { + uint64_t begin; + size_t size; + uint32_t perms; +} MemoryBlock; + typedef struct ModuleEntry { void (*init)(void); QTAILQ_ENTRY(ModuleEntry) node; @@ -165,11 +171,13 @@ struct uc_struct { int thumb; // thumb mode for ARM // full TCG cache leads to middle-block break in the last translation? bool block_full; + MemoryBlock *mapped_blocks; + uint32_t mapped_block_count; }; #include "qemu_macro.h" // check if this address is mapped in (via uc_mem_map()) -bool memory_mapping(uint64_t address); +bool memory_mapping(struct uc_struct* uc, uint64_t address); #endif diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h old mode 100644 new mode 100755 index 66de81eb..ebdb47f3 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -384,6 +384,12 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us UNICORN_EXPORT uc_err uc_hook_del(uch handle, uch *h2); +typedef enum uc_prot { + UC_PROT_READ = 1, + UC_PROT_WRITE = 2, + UC_PROT_EXEC = 4 +} uc_prot; + /* Map memory in for emulation. This API adds a memory region that can be used by emulation. diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h old mode 100644 new mode 100755 index 3fca97ec..fa0bd630 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -188,7 +188,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, } // Unicorn: callback on invalid memory - if (!memory_mapping(addr) && env->uc->hook_mem_idx) { + if (!memory_mapping(env->uc, addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( (uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { @@ -306,7 +306,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, } // Unicorn: callback on invalid memory - if (!memory_mapping(addr) && env->uc->hook_mem_idx) { + if (!memory_mapping(env->uc, addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( (uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { @@ -464,7 +464,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, } // Unicorn: callback on invalid memory - if (!memory_mapping(addr) && env->uc->hook_mem_idx) { + if (!memory_mapping(env->uc, addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { @@ -576,7 +576,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, } // Unicorn: callback on invalid memory - if (!memory_mapping(addr) && env->uc->hook_mem_idx) { + if (!memory_mapping(env->uc, addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { diff --git a/uc.c b/uc.c old mode 100644 new mode 100755 index 5a798f57..41280a98 --- a/uc.c +++ b/uc.c @@ -31,11 +31,6 @@ #include "qemu/include/hw/boards.h" -// TODO -static uint64_t map_begin[32], map_end[32]; -static int map_count = 0; - - UNICORN_EXPORT unsigned int uc_version(unsigned int *major, unsigned int *minor) { @@ -534,6 +529,7 @@ static uc_err _hook_mem_access(uch handle, uc_mem_type type, UNICORN_EXPORT uc_err uc_mem_map(uch handle, uint64_t address, size_t size) { + MemoryBlock *blocks; struct uc_struct* uc = (struct uc_struct *)handle; if (handle == 0) @@ -552,20 +548,27 @@ uc_err uc_mem_map(uch handle, uint64_t address, size_t size) if ((size & (4*1024 - 1)) != 0) return UC_ERR_MAP; - map_begin[map_count] = address; - map_end[map_count] = size + map_begin[map_count]; - uc->memory_map(uc, map_begin[map_count], size); - map_count++; + blocks = realloc(uc->mapped_blocks, sizeof(MemoryBlock) * (uc->mapped_block_count + 1)); + if (blocks == NULL) { + return UC_ERR_OOM; + } + uc->mapped_blocks = blocks; + blocks[uc->mapped_block_count].begin = address; + blocks[uc->mapped_block_count].size = size; + //TODO extend uc_mem_map to accept permissions, figure out how to pass this down to qemu + blocks[uc->mapped_block_count].perms = UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC; + uc->memory_map(uc, address, size); + uc->mapped_block_count++; return UC_ERR_OK; } -bool memory_mapping(uint64_t address) +bool memory_mapping(struct uc_struct* uc, uint64_t address) { unsigned int i; - for(i = 0; i < map_count; i++) { - if (address >= map_begin[i] && address <= map_end[i]) + for(i = 0; i < uc->mapped_block_count; i++) { + if (address >= uc->mapped_blocks[i].begin && address < (uc->mapped_blocks[i].begin + uc->mapped_blocks[i].size)) return true; }