First cut at cleaning up uc_mem_map, eliminate map_begin and map_end, move tracking inside uc struct

This commit is contained in:
Chris Eagle 2015-08-25 21:52:18 -07:00
parent c1514609b1
commit 03e8b28d71
4 changed files with 34 additions and 17 deletions

10
include/uc_priv.h Normal file → Executable file
View File

@ -15,6 +15,12 @@
QTAILQ_HEAD(CPUTailQ, CPUState); QTAILQ_HEAD(CPUTailQ, CPUState);
typedef struct MemoryBlock {
uint64_t begin;
size_t size;
uint32_t perms;
} MemoryBlock;
typedef struct ModuleEntry { typedef struct ModuleEntry {
void (*init)(void); void (*init)(void);
QTAILQ_ENTRY(ModuleEntry) node; QTAILQ_ENTRY(ModuleEntry) node;
@ -165,11 +171,13 @@ struct uc_struct {
int thumb; // thumb mode for ARM int thumb; // thumb mode for ARM
// full TCG cache leads to middle-block break in the last translation? // full TCG cache leads to middle-block break in the last translation?
bool block_full; bool block_full;
MemoryBlock *mapped_blocks;
uint32_t mapped_block_count;
}; };
#include "qemu_macro.h" #include "qemu_macro.h"
// check if this address is mapped in (via uc_mem_map()) // 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 #endif

6
include/unicorn/unicorn.h Normal file → Executable file
View File

@ -384,6 +384,12 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us
UNICORN_EXPORT UNICORN_EXPORT
uc_err uc_hook_del(uch handle, uch *h2); 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. Map memory in for emulation.
This API adds a memory region that can be used by emulation. This API adds a memory region that can be used by emulation.

8
qemu/softmmu_template.h Normal file → Executable file
View File

@ -188,7 +188,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
} }
// Unicorn: callback on invalid memory // 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)( 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, (uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { 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 // 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)( 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, (uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { 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 // 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)( 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, (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { 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 // 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)( 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, (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) {

27
uc.c Normal file → Executable file
View File

@ -31,11 +31,6 @@
#include "qemu/include/hw/boards.h" #include "qemu/include/hw/boards.h"
// TODO
static uint64_t map_begin[32], map_end[32];
static int map_count = 0;
UNICORN_EXPORT UNICORN_EXPORT
unsigned int uc_version(unsigned int *major, unsigned int *minor) 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 UNICORN_EXPORT
uc_err uc_mem_map(uch handle, uint64_t address, size_t size) uc_err uc_mem_map(uch handle, uint64_t address, size_t size)
{ {
MemoryBlock *blocks;
struct uc_struct* uc = (struct uc_struct *)handle; struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0) 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) if ((size & (4*1024 - 1)) != 0)
return UC_ERR_MAP; return UC_ERR_MAP;
map_begin[map_count] = address; blocks = realloc(uc->mapped_blocks, sizeof(MemoryBlock) * (uc->mapped_block_count + 1));
map_end[map_count] = size + map_begin[map_count]; if (blocks == NULL) {
uc->memory_map(uc, map_begin[map_count], size); return UC_ERR_OOM;
map_count++; }
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; return UC_ERR_OK;
} }
bool memory_mapping(uint64_t address) bool memory_mapping(struct uc_struct* uc, uint64_t address)
{ {
unsigned int i; unsigned int i;
for(i = 0; i < map_count; i++) { for(i = 0; i < uc->mapped_block_count; i++) {
if (address >= map_begin[i] && address <= map_end[i]) if (address >= uc->mapped_blocks[i].begin && address < (uc->mapped_blocks[i].begin + uc->mapped_blocks[i].size))
return true; return true;
} }