Merge branch 'master' of https://github.com/unicorn-engine/unicorn
This commit is contained in:
@@ -51,7 +51,5 @@ void mips_machine_init(struct uc_struct *uc)
|
||||
.arch = UC_ARCH_MIPS,
|
||||
};
|
||||
|
||||
printf(">>> mips_machine_init\n");
|
||||
|
||||
qemu_register_machine(uc, &mips_machine, TYPE_MACHINE, NULL);
|
||||
}
|
||||
|
||||
@@ -177,27 +177,35 @@ 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;
|
||||
|
||||
struct uc_struct *uc = env->uc;
|
||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||
|
||||
// memory can be unmapped while reading or fetching
|
||||
if (mr == NULL) {
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
// Unicorn: callback on fetch from unmapped memory
|
||||
if (mr == NULL) { // memory is not mapped
|
||||
mem_access = UC_MEM_FETCH;
|
||||
error_code = UC_ERR_FETCH_INVALID;
|
||||
#else
|
||||
mem_access = UC_MEM_READ;
|
||||
error_code = UC_ERR_READ_INVALID;
|
||||
#endif
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_FETCH, addr, DATA_SIZE, 0,
|
||||
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 {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_FETCH;
|
||||
env->invalid_error = error_code;
|
||||
// printf("***** Invalid fetch (unmapped memory) at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#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)(
|
||||
@@ -223,22 +231,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
}
|
||||
}
|
||||
|
||||
// Unicorn: callback on invalid memory
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && env->uc->hook_mem_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)(
|
||||
env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
|
||||
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_READ;
|
||||
// printf("***** Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return 0;
|
||||
} else {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)(
|
||||
@@ -263,8 +255,16 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
|
||||
#ifdef ALIGNED_ONLY
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!VICTIM_TLB_HIT(ADDR_READ)) {
|
||||
@@ -283,7 +283,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
ioaddr = env->iotlb[mmu_idx][index];
|
||||
if (ioaddr == 0) {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_READ;
|
||||
env->invalid_error = UC_ERR_READ_INVALID;
|
||||
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return 0;
|
||||
@@ -307,8 +307,16 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
unsigned shift;
|
||||
do_unaligned_access:
|
||||
#ifdef ALIGNED_ONLY
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
#endif
|
||||
addr1 = addr & ~(DATA_SIZE - 1);
|
||||
addr2 = addr1 + DATA_SIZE;
|
||||
@@ -326,8 +334,16 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
/* Handle aligned access or unaligned access in the same page. */
|
||||
#ifdef ALIGNED_ONLY
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -351,27 +367,35 @@ 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;
|
||||
|
||||
struct uc_struct *uc = env->uc;
|
||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||
|
||||
// memory can be unmapped while reading or fetching
|
||||
if (mr == NULL) {
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
// Unicorn: callback on fetch from unmapped memory
|
||||
if (mr == NULL) { // memory is not mapped
|
||||
mem_access = UC_MEM_FETCH;
|
||||
error_code = UC_ERR_FETCH_INVALID;
|
||||
#else
|
||||
mem_access = UC_MEM_READ;
|
||||
error_code = UC_ERR_READ_INVALID;
|
||||
#endif
|
||||
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
|
||||
uc, UC_MEM_FETCH, addr, DATA_SIZE, 0,
|
||||
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 {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_FETCH;
|
||||
env->invalid_error = error_code;
|
||||
// printf("***** Invalid fetch (unmapped memory) at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#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)(
|
||||
@@ -397,22 +421,6 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
}
|
||||
}
|
||||
|
||||
// Unicorn: callback on invalid memory
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && env->uc->hook_mem_idx && mr == NULL) {
|
||||
if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)(
|
||||
env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
|
||||
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_READ;
|
||||
// printf("***** Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return 0;
|
||||
} else {
|
||||
env->invalid_error = UC_ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)(
|
||||
@@ -436,8 +444,16 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
|
||||
#ifdef ALIGNED_ONLY
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!VICTIM_TLB_HIT(ADDR_READ)) {
|
||||
@@ -457,7 +473,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
|
||||
if (ioaddr == 0) {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_READ;
|
||||
env->invalid_error = UC_ERR_READ_INVALID;
|
||||
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return 0;
|
||||
@@ -479,8 +495,16 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
unsigned shift;
|
||||
do_unaligned_access:
|
||||
#ifdef ALIGNED_ONLY
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
#endif
|
||||
addr1 = addr & ~(DATA_SIZE - 1);
|
||||
addr2 = addr1 + DATA_SIZE;
|
||||
@@ -498,8 +522,16 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
/* Handle aligned access or unaligned access in the same page. */
|
||||
#ifdef ALIGNED_ONLY
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
env->invalid_error = UC_ERR_FETCH_UNALIGNED;
|
||||
#else
|
||||
env->invalid_error = UC_ERR_READ_UNALIGNED;
|
||||
#endif
|
||||
cpu_exit(uc->current_cpu);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -582,7 +614,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_WRITE;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
@@ -615,8 +647,12 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
|
||||
#ifdef ALIGNED_ONLY
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
//cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
// mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!VICTIM_TLB_HIT(addr_write)) {
|
||||
@@ -634,7 +670,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
ioaddr = env->iotlb[mmu_idx][index];
|
||||
if (ioaddr == 0) {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_WRITE;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return;
|
||||
@@ -656,6 +692,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
#ifdef ALIGNED_ONLY
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
#endif
|
||||
/* XXX: not efficient, but simple */
|
||||
/* Note: relies on the fact that tlb_fill() does not remove the
|
||||
@@ -678,6 +718,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -716,7 +760,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
|
||||
// save error & quit
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_WRITE;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
@@ -751,6 +795,10 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!VICTIM_TLB_HIT(addr_write)) {
|
||||
@@ -768,7 +816,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
ioaddr = env->iotlb[mmu_idx][index];
|
||||
if (ioaddr == 0) {
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_MEM_WRITE;
|
||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||
cpu_exit(env->uc->current_cpu);
|
||||
return;
|
||||
@@ -790,6 +838,10 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
#ifdef ALIGNED_ONLY
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
#endif
|
||||
/* XXX: not efficient, but simple */
|
||||
/* Note: relies on the fact that tlb_fill() does not remove the
|
||||
@@ -812,6 +864,10 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if ((addr & (DATA_SIZE - 1)) != 0) {
|
||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
env->invalid_addr = addr;
|
||||
env->invalid_error = UC_ERR_WRITE_UNALIGNED;
|
||||
cpu_exit(uc->current_cpu);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -156,6 +156,5 @@ void mips_cpu_register_types(void *opaque)
|
||||
.class_init = mips_cpu_class_init,
|
||||
};
|
||||
|
||||
printf(">>> mips_cpu_register_types\n");
|
||||
type_register_static(opaque, &mips_cpu_type_info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user