From 065af19dc5b60a4a0c650b1c13979dde80d0f502 Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Thu, 22 Dec 2022 12:20:36 +0100 Subject: [PATCH] use address_space_translate to find memory mapping first version has bugs --- include/uc_priv.h | 6 +++--- qemu/aarch64.h | 1 + qemu/accel/tcg/cputlb.c | 8 ++++---- qemu/arm.h | 1 + qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/ppc.h | 1 + qemu/ppc64.h | 1 + qemu/riscv32.h | 1 + qemu/riscv64.h | 1 + qemu/s390x.h | 1 + qemu/softmmu/memory.c | 2 +- qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/tricore.h | 1 + qemu/unicorn_common.h | 13 +++++++++++++ qemu/x86_64.h | 1 + symbols.sh | 1 + uc.c | 5 ++++- 22 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index ef3d30e3..a6c86e70 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -100,6 +100,8 @@ typedef MemoryRegion *(*uc_args_uc_ram_size_ptr_t)(struct uc_struct *, typedef void (*uc_mem_unmap_t)(struct uc_struct *, MemoryRegion *mr); +typedef MemoryRegion *(*uc_memory_mapping_t)(struct uc_struct *, hwaddr addr); + typedef void (*uc_readonly_mem_t)(MemoryRegion *mr, bool readonly); typedef int (*uc_cpus_init)(struct uc_struct *, const char *); @@ -277,6 +279,7 @@ struct uc_struct { uc_args_uc_long_t tcg_exec_init; uc_args_uc_ram_size_t memory_map; uc_args_uc_ram_size_ptr_t memory_map_ptr; + uc_memory_mapping_t memory_mapping; uc_mem_unmap_t memory_unmap; uc_readonly_mem_t readonly_mem; uc_cpus_init cpus_init; @@ -410,9 +413,6 @@ struct uc_context { char data[0]; // context }; -// check if this address is mapped in (via uc_mem_map()) -MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address); - // We have to support 32bit system so we can't hold uint64_t on void* static inline void uc_add_exit(uc_engine *uc, uint64_t addr) { diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 6e17c390..d7349535 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_aarch64 #define memory_region_init_ram memory_region_init_ram_aarch64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_aarch64 +#define find_memory_mapping find_memory_mapping_aarch64 #define exec_inline_op exec_inline_op_aarch64 #define floatx80_default_nan floatx80_default_nan_aarch64 #define float_raise float_raise_aarch64 diff --git a/qemu/accel/tcg/cputlb.c b/qemu/accel/tcg/cputlb.c index f805b44a..e4c2d9a3 100644 --- a/qemu/accel/tcg/cputlb.c +++ b/qemu/accel/tcg/cputlb.c @@ -1460,7 +1460,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, } paddr = entry->paddr | (addr & ~TARGET_PAGE_MASK); - mr = find_memory_region(uc, paddr); + mr = uc->memory_mapping(uc, paddr); // memory might be still unmapped while reading or fetching if (mr == NULL) { @@ -1517,7 +1517,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, tlb_addr &= ~TLB_INVALID_MASK; } paddr = entry->paddr | (addr & ~TARGET_PAGE_MASK); - mr = find_memory_region(uc, paddr); + mr = uc->memory_mapping(uc, paddr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; if (uc->nested_level > 0 && !uc->cpu->stopped) { @@ -2053,7 +2053,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, // Load the latest memory mapping. paddr = entry->paddr | (addr & ~TARGET_PAGE_MASK); - mr = find_memory_region(uc, paddr); + mr = uc->memory_mapping(uc, paddr); if (!uc->size_recur_mem) { // disabling write callback if in recursive call // Unicorn: callback on memory write @@ -2107,7 +2107,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK; } paddr = entry->paddr | (addr & ~TARGET_PAGE_MASK); - mr = find_memory_region(uc, paddr); + mr = uc->memory_mapping(uc, paddr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; cpu_exit(uc->cpu); diff --git a/qemu/arm.h b/qemu/arm.h index 3676b360..1fe1fc5c 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_arm #define memory_region_init_ram memory_region_init_ram_arm #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_arm +#define find_memory_mapping find_memory_mapping_arm #define exec_inline_op exec_inline_op_arm #define floatx80_default_nan floatx80_default_nan_arm #define float_raise float_raise_arm diff --git a/qemu/m68k.h b/qemu/m68k.h index 061297d6..d4a7c133 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_m68k #define memory_region_init_ram memory_region_init_ram_m68k #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_m68k +#define find_memory_mapping find_memory_mapping_m68k #define exec_inline_op exec_inline_op_m68k #define floatx80_default_nan floatx80_default_nan_m68k #define float_raise float_raise_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 98447291..44d22db0 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_mips #define memory_region_init_ram memory_region_init_ram_mips #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_mips +#define find_memory_mapping find_memory_mapping_mips #define exec_inline_op exec_inline_op_mips #define floatx80_default_nan floatx80_default_nan_mips #define float_raise float_raise_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 8a7dbe77..759f4552 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_mips64 #define memory_region_init_ram memory_region_init_ram_mips64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_mips64 +#define find_memory_mapping find_memory_mapping_mips64 #define exec_inline_op exec_inline_op_mips64 #define floatx80_default_nan floatx80_default_nan_mips64 #define float_raise float_raise_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 5ae511bc..4700a912 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_mips64el #define memory_region_init_ram memory_region_init_ram_mips64el #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_mips64el +#define find_memory_mapping find_memory_mapping_mips64el #define exec_inline_op exec_inline_op_mips64el #define floatx80_default_nan floatx80_default_nan_mips64el #define float_raise float_raise_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index dc0a2a41..f42638b0 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_mipsel #define memory_region_init_ram memory_region_init_ram_mipsel #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_mipsel +#define find_memory_mapping find_memory_mapping_mipsel #define exec_inline_op exec_inline_op_mipsel #define floatx80_default_nan floatx80_default_nan_mipsel #define float_raise float_raise_mipsel diff --git a/qemu/ppc.h b/qemu/ppc.h index d2761616..a2a7a814 100644 --- a/qemu/ppc.h +++ b/qemu/ppc.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_ppc #define memory_region_init_ram memory_region_init_ram_ppc #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_ppc +#define find_memory_mapping find_memory_mapping_ppc #define exec_inline_op exec_inline_op_ppc #define floatx80_default_nan floatx80_default_nan_ppc #define float_raise float_raise_ppc diff --git a/qemu/ppc64.h b/qemu/ppc64.h index 51f94d12..07f0a5ce 100644 --- a/qemu/ppc64.h +++ b/qemu/ppc64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_ppc64 #define memory_region_init_ram memory_region_init_ram_ppc64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_ppc64 +#define find_memory_mapping find_memory_mapping_ppc64 #define exec_inline_op exec_inline_op_ppc64 #define floatx80_default_nan floatx80_default_nan_ppc64 #define float_raise float_raise_ppc64 diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 8d373290..a33a0068 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_riscv32 #define memory_region_init_ram memory_region_init_ram_riscv32 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_riscv32 +#define find_memory_mapping find_memory_mapping_riscv32 #define exec_inline_op exec_inline_op_riscv32 #define floatx80_default_nan floatx80_default_nan_riscv32 #define float_raise float_raise_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index e1593cde..ba926a07 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_riscv64 #define memory_region_init_ram memory_region_init_ram_riscv64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_riscv64 +#define find_memory_mapping find_memory_mapping_riscv64 #define exec_inline_op exec_inline_op_riscv64 #define floatx80_default_nan floatx80_default_nan_riscv64 #define float_raise float_raise_riscv64 diff --git a/qemu/s390x.h b/qemu/s390x.h index b2350ce2..e989949b 100644 --- a/qemu/s390x.h +++ b/qemu/s390x.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_s390x #define memory_region_init_ram memory_region_init_ram_s390x #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_s390x +#define find_memory_mapping find_memory_mapping_s390x #define exec_inline_op exec_inline_op_s390x #define floatx80_default_nan floatx80_default_nan_s390x #define float_raise float_raise_s390x diff --git a/qemu/softmmu/memory.c b/qemu/softmmu/memory.c index a0fdf5fb..9e3e9a77 100644 --- a/qemu/softmmu/memory.c +++ b/qemu/softmmu/memory.c @@ -179,8 +179,8 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) int memory_free(struct uc_struct *uc) { - MemoryRegion *mr; int i; + MemoryRegion *mr; for (i = 0; i < uc->mapped_block_count; i++) { mr = uc->mapped_blocks[i]; diff --git a/qemu/sparc.h b/qemu/sparc.h index 75ec3b29..d5effee6 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_sparc #define memory_region_init_ram memory_region_init_ram_sparc #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_sparc +#define find_memory_mapping find_memory_mapping_sparc #define exec_inline_op exec_inline_op_sparc #define floatx80_default_nan floatx80_default_nan_sparc #define float_raise float_raise_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 89ad6790..462466cf 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_sparc64 #define memory_region_init_ram memory_region_init_ram_sparc64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_sparc64 +#define find_memory_mapping find_memory_mapping_sparc64 #define exec_inline_op exec_inline_op_sparc64 #define floatx80_default_nan floatx80_default_nan_sparc64 #define float_raise float_raise_sparc64 diff --git a/qemu/tricore.h b/qemu/tricore.h index 560e868e..28b6f82d 100644 --- a/qemu/tricore.h +++ b/qemu/tricore.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_tricore #define memory_region_init_ram memory_region_init_ram_tricore #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_tricore +#define find_memory_mapping find_memory_mapping_tricore #define exec_inline_op exec_inline_op_tricore #define floatx80_default_nan floatx80_default_nan_tricore #define float_raise float_raise_tricore diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 1a622fe7..10252c05 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -107,6 +107,18 @@ static uc_err uc_set_tlb(struct uc_struct *uc, int mode) { } } +MemoryRegion *find_memory_mapping(struct uc_struct *uc, hwaddr address) +{ + hwaddr xlat = 0; + hwaddr len = 1; + MemoryRegion *mr = address_space_translate(&uc->address_space_memory, address, &xlat, &len, false, MEMTXATTRS_UNSPECIFIED); + + if (mr == &uc->io_mem_unassigned) { + return NULL; + } + return mr; +} + void softfloat_init(void); static inline void uc_common_init(struct uc_struct* uc) { @@ -124,6 +136,7 @@ static inline void uc_common_init(struct uc_struct* uc) uc->tcg_flush_tlb = tcg_flush_softmmu_tlb; uc->memory_map_io = memory_map_io; uc->set_tlb = uc_set_tlb; + uc->memory_mapping = find_memory_mapping; if (!uc->release) uc->release = release_common; diff --git a/qemu/x86_64.h b/qemu/x86_64.h index a52f8e13..a118e747 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -151,6 +151,7 @@ #define address_space_destroy address_space_destroy_x86_64 #define memory_region_init_ram memory_region_init_ram_x86_64 #define memory_mapping_list_add_merge_sorted memory_mapping_list_add_merge_sorted_x86_64 +#define find_memory_mapping find_memory_mapping_x86_64 #define exec_inline_op exec_inline_op_x86_64 #define floatx80_default_nan floatx80_default_nan_x86_64 #define float_raise float_raise_x86_64 diff --git a/symbols.sh b/symbols.sh index 6a21a98b..80f213b6 100755 --- a/symbols.sh +++ b/symbols.sh @@ -151,6 +151,7 @@ address_space_init \ address_space_destroy \ memory_region_init_ram \ memory_mapping_list_add_merge_sorted \ +find_memory_mapping \ exec_inline_op \ floatx80_default_nan \ float_raise \ diff --git a/uc.c b/uc.c index b92dddc1..7eb4beea 100644 --- a/uc.c +++ b/uc.c @@ -31,6 +31,7 @@ #include "qemu-common.h" static void clear_deleted_hooks(uc_engine *uc); +static MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address); static void *hook_insert(struct list *l, struct hook *h) { @@ -1083,12 +1084,14 @@ static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size) return true; // not found + return false; } // common setup/error checking shared between uc_mem_map and uc_mem_map_ptr static uc_err mem_map(uc_engine *uc, MemoryRegion *block) { + MemoryRegion **regions; int pos; @@ -1609,7 +1612,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) } // find the memory region of this address -MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) +static MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) { unsigned int i;