This commit continues the PR #111
- Allow to register handler separately for invalid memory access - Add new memory events for hooking: - UC_MEM_READ_INVALID, UC_MEM_WRITE_INVALID, UC_MEM_FETCH_INVALID - UC_HOOK_MEM_READ_PROT, UC_HOOK_MEM_WRITE_PROT, UC_HOOK_MEM_FETCH_PROT - Rename UC_ERR_EXEC_PROT to UC_ERR_FETCH_PROT - Change API uc_hook_add() so event type @type can be combined from hooking types
This commit is contained in:
@@ -300,7 +300,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
||||
(addr & TARGET_PAGE_MASK))) {
|
||||
cpu_ldub_code(env1, addr);
|
||||
//check for NX related error from softmmu
|
||||
if (env1->invalid_error == UC_ERR_EXEC_PROT) {
|
||||
if (env1->invalid_error == UC_ERR_FETCH_PROT) {
|
||||
env1->invalid_error = UC_ERR_CODE_INVALID;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
|
||||
uintptr_t haddr;
|
||||
DATA_TYPE res;
|
||||
int mem_access, error_code;
|
||||
int error_code;
|
||||
|
||||
struct uc_struct *uc = env->uc;
|
||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||
@@ -185,15 +185,16 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
// memory can be unmapped while reading or fetching
|
||||
if (mr == NULL) {
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
mem_access = UC_MEM_FETCH;
|
||||
error_code = UC_ERR_FETCH_INVALID;
|
||||
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
||||
uc, UC_MEM_FETCH_INVALID, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
||||
#else
|
||||
mem_access = UC_MEM_READ;
|
||||
error_code = UC_ERR_READ_INVALID;
|
||||
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
||||
uc, UC_MEM_READ_INVALID, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
||||
#endif
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, mem_access, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
mr = memory_mapping(uc, addr); // FIXME: what if mr is still NULL at this time?
|
||||
} else {
|
||||
@@ -208,13 +209,13 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
// Unicorn: callback on fetch from NX
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
if (uc->hook_mem_fetch_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_prot_idx].callback)(
|
||||
uc, UC_MEM_FETCH_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_fetch_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
} else {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_EXEC_PROT;
|
||||
env->invalid_error = UC_ERR_FETCH_PROT;
|
||||
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
@@ -233,9 +234,9 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
|
||||
// Unicorn: callback on non-readable memory
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
if (uc->hook_mem_read_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_prot_idx].callback)(
|
||||
uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
uc->hook_callbacks[uc->hook_mem_read_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
}
|
||||
else {
|
||||
@@ -367,7 +368,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
|
||||
uintptr_t haddr;
|
||||
DATA_TYPE res;
|
||||
int mem_access, error_code;
|
||||
int error_code;
|
||||
|
||||
struct uc_struct *uc = env->uc;
|
||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||
@@ -375,15 +376,16 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
// memory can be unmapped while reading or fetching
|
||||
if (mr == NULL) {
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
mem_access = UC_MEM_FETCH;
|
||||
error_code = UC_ERR_FETCH_INVALID;
|
||||
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
||||
uc, UC_MEM_FETCH_INVALID, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
||||
#else
|
||||
mem_access = UC_MEM_READ;
|
||||
error_code = UC_ERR_READ_INVALID;
|
||||
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
||||
uc, UC_MEM_READ_INVALID, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
||||
#endif
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, mem_access, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
mr = memory_mapping(uc, addr); // FIXME: what if mr is still NULL at this time?
|
||||
} else {
|
||||
@@ -398,13 +400,13 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
// Unicorn: callback on fetch from NX
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
if (uc->hook_mem_fetch_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_prot_idx].callback)(
|
||||
uc, UC_MEM_FETCH_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_fetch_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
} else {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_EXEC_PROT;
|
||||
env->invalid_error = UC_ERR_FETCH_PROT;
|
||||
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
@@ -423,9 +425,9 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
|
||||
// Unicorn: callback on non-readable memory
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
if (uc->hook_mem_read_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_prot_idx].callback)(
|
||||
uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
uc->hook_callbacks[uc->hook_mem_read_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
} else {
|
||||
env->invalid_addr = addr;
|
||||
@@ -608,10 +610,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
}
|
||||
|
||||
// Unicorn: callback on invalid memory
|
||||
if (uc->hook_mem_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
if (uc->hook_mem_write_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
||||
uc, UC_MEM_WRITE_INVALID, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
@@ -620,14 +622,15 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
return;
|
||||
} else {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
mr = memory_mapping(uc, addr); // FIXME: what if mr is still NULL at this time?
|
||||
}
|
||||
}
|
||||
|
||||
// Unicorn: callback on non-writable memory
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
if (uc->hook_mem_write_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_prot_idx].callback)(
|
||||
uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
uc->hook_callbacks[uc->hook_mem_write_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
}
|
||||
else {
|
||||
@@ -754,10 +757,10 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
}
|
||||
|
||||
// Unicorn: callback on invalid memory
|
||||
if (uc->hook_mem_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
if (uc->hook_mem_write_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
||||
uc, UC_MEM_WRITE_INVALID, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
@@ -766,14 +769,15 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
return;
|
||||
} else {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
mr = memory_mapping(uc, addr); // FIXME: what if mr is still NULL at this time?
|
||||
}
|
||||
}
|
||||
|
||||
// Unicorn: callback on non-writable memory
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
if (uc->hook_mem_write_prot_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_prot_idx].callback)(
|
||||
uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
uc->hook_callbacks[uc->hook_mem_write_prot_idx].user_data)) {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user