Merge remote-tracking branch 'upstream/master' into change-handle-based-api

This commit is contained in:
Jonathon Reinhart
2015-09-03 22:01:52 -04:00
33 changed files with 1369 additions and 99 deletions

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_aarch64
#define tb_cleanup tb_cleanup_aarch64
#define memory_map memory_map_aarch64
#define memory_unmap memory_unmap_aarch64
#define memory_free memory_free_aarch64
#define helper_raise_exception helper_raise_exception_aarch64
#define tcg_enabled tcg_enabled_aarch64

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_arm
#define tb_cleanup tb_cleanup_arm
#define memory_map memory_map_arm
#define memory_unmap memory_unmap_arm
#define memory_free memory_free_arm
#define helper_raise_exception helper_raise_exception_arm
#define tcg_enabled tcg_enabled_arm

View File

@ -299,6 +299,11 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
(addr & TARGET_PAGE_MASK))) {
cpu_ldub_code(env1, addr);
//check for NX related error from softmmu
if (env1->invalid_error == UC_ERR_MEM_READ) {
env1->invalid_error = UC_ERR_CODE_INVALID;
return -1;
}
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu->as, pd);

View File

@ -13,6 +13,7 @@ symbols = (
'phys_mem_clean',
'tb_cleanup',
'memory_map',
'memory_unmap',
'memory_free',
'helper_raise_exception',
'tcg_enabled',

View File

@ -939,6 +939,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
void memory_register_types(struct uc_struct *uc);
MemoryRegion *memory_map(struct uc_struct *uc, ram_addr_t begin, size_t size, uint32_t perms);
void memory_unmap(struct uc_struct *uc, MemoryRegion *mr);
int memory_free(struct uc_struct *uc);
#endif

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_m68k
#define tb_cleanup tb_cleanup_m68k
#define memory_map memory_map_m68k
#define memory_unmap memory_unmap_m68k
#define memory_free memory_free_m68k
#define helper_raise_exception helper_raise_exception_m68k
#define tcg_enabled tcg_enabled_m68k

View File

@ -45,6 +45,29 @@ MemoryRegion *memory_map(struct uc_struct *uc, ram_addr_t begin, size_t size, ui
return ram;
}
void memory_unmap(struct uc_struct *uc, MemoryRegion *mr)
{
int i;
target_ulong addr;
//make sure all pages associated with the MemoryRegion are flushed
for (addr = mr->addr; addr < mr->end; addr += uc->target_page_size) {
tlb_flush_page(uc->current_cpu, addr);
}
mr->enabled = false;
memory_region_del_subregion(get_system_memory(uc), mr);
for (i = 0; i < uc->mapped_block_count; i++) {
if (uc->mapped_blocks[i] == mr) {
uc->mapped_block_count--;
//shift remainder of array down over deleted pointer
memcpy(&uc->mapped_blocks[i], &uc->mapped_blocks[i + 1], sizeof(MemoryRegion*) * (uc->mapped_block_count - i));
break;
}
}
g_free(mr);
}
int memory_free(struct uc_struct *uc)
{
int i;

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips
#define tb_cleanup tb_cleanup_mips
#define memory_map memory_map_mips
#define memory_unmap memory_unmap_mips
#define memory_free memory_free_mips
#define helper_raise_exception helper_raise_exception_mips
#define tcg_enabled tcg_enabled_mips

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips64
#define tb_cleanup tb_cleanup_mips64
#define memory_map memory_map_mips64
#define memory_unmap memory_unmap_mips64
#define memory_free memory_free_mips64
#define helper_raise_exception helper_raise_exception_mips64
#define tcg_enabled tcg_enabled_mips64

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mips64el
#define tb_cleanup tb_cleanup_mips64el
#define memory_map memory_map_mips64el
#define memory_unmap memory_unmap_mips64el
#define memory_free memory_free_mips64el
#define helper_raise_exception helper_raise_exception_mips64el
#define tcg_enabled tcg_enabled_mips64el

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_mipsel
#define tb_cleanup tb_cleanup_mipsel
#define memory_map memory_map_mipsel
#define memory_unmap memory_unmap_mipsel
#define memory_free memory_free_mipsel
#define helper_raise_exception helper_raise_exception_mipsel
#define tcg_enabled tcg_enabled_mipsel

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_powerpc
#define tb_cleanup tb_cleanup_powerpc
#define memory_map memory_map_powerpc
#define memory_unmap memory_unmap_powerpc
#define memory_free memory_free_powerpc
#define helper_raise_exception helper_raise_exception_powerpc
#define tcg_enabled tcg_enabled_powerpc

View File

@ -181,6 +181,23 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
struct uc_struct *uc = env->uc;
MemoryRegion *mr = memory_mapping(uc, addr);
#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)(
(uch)uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
} else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_EXEC_PROT;
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return 0;
}
}
#endif
// Unicorn: callback on memory read
if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) {
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_MEM_READ, addr);
@ -206,20 +223,16 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
}
}
// Unicorn: callback on read only memory
// Unicorn: callback on non-readable memory
if (mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
}
else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_MEM_READ_NR;
env->invalid_error = UC_ERR_READ_PROT;
// printf("***** Invalid memory read (non-readable) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return 0;
@ -326,6 +339,23 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
struct uc_struct *uc = env->uc;
MemoryRegion *mr = memory_mapping(uc, addr);
#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)(
(uch)uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
} else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_EXEC_PROT;
// printf("***** Invalid fetch (non-executable) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return 0;
}
}
#endif
// Unicorn: callback on memory read
if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) {
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_MEM_READ, addr);
@ -351,20 +381,15 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
}
}
// Unicorn: callback on read only memory
// Unicorn: callback on non-readable memory
if (mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
}
else {
} else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_MEM_READ_NR;
env->invalid_error = UC_ERR_READ_PROT;
// printf("***** Invalid memory read (non-readable) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return 0;
@ -534,20 +559,16 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}
}
// Unicorn: callback on read only memory
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //read only memory
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
// 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)(
uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
}
else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_MEM_WRITE_NW;
env->invalid_error = UC_ERR_WRITE_PROT;
// printf("***** Invalid memory write (ro) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return;
@ -672,20 +693,16 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}
}
// Unicorn: callback on read only memory
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //read only memory
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
// 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)(
uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
env->invalid_error = UC_ERR_OK;
}
else {
env->invalid_addr = addr;
env->invalid_error = UC_ERR_MEM_WRITE_NW;
env->invalid_error = UC_ERR_WRITE_PROT;
// printf("***** Invalid memory write (ro) at " TARGET_FMT_lx "\n", addr);
cpu_exit(uc->current_cpu);
return;

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_sparc
#define tb_cleanup tb_cleanup_sparc
#define memory_map memory_map_sparc
#define memory_unmap memory_unmap_sparc
#define memory_free memory_free_sparc
#define helper_raise_exception helper_raise_exception_sparc
#define tcg_enabled tcg_enabled_sparc

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_sparc64
#define tb_cleanup tb_cleanup_sparc64
#define memory_map memory_map_sparc64
#define memory_unmap memory_unmap_sparc64
#define memory_free memory_free_sparc64
#define helper_raise_exception helper_raise_exception_sparc64
#define tcg_enabled tcg_enabled_sparc64

View File

@ -73,8 +73,12 @@ static inline void uc_common_init(struct uc_struct* uc)
uc->pause_all_vcpus = pause_all_vcpus;
uc->vm_start = vm_start;
uc->memory_map = memory_map;
uc->memory_unmap = memory_unmap;
uc->readonly_mem = memory_region_set_readonly;
uc->target_page_size = TARGET_PAGE_SIZE;
uc->target_page_align = TARGET_PAGE_SIZE - 1;
if (!uc->release)
uc->release = release_common;
}

View File

@ -7,6 +7,7 @@
#define phys_mem_clean phys_mem_clean_x86_64
#define tb_cleanup tb_cleanup_x86_64
#define memory_map memory_map_x86_64
#define memory_unmap memory_unmap_x86_64
#define memory_free memory_free_x86_64
#define helper_raise_exception helper_raise_exception_x86_64
#define tcg_enabled tcg_enabled_x86_64