First cut at cleaning up uc_mem_map, eliminate map_begin and map_end, move tracking inside uc struct
This commit is contained in:
parent
c1514609b1
commit
03e8b28d71
10
include/uc_priv.h
Normal file → Executable file
10
include/uc_priv.h
Normal file → Executable 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
6
include/unicorn/unicorn.h
Normal file → Executable 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
8
qemu/softmmu_template.h
Normal file → Executable 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
27
uc.c
Normal file → Executable 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user