From 30d202b89e5f9efe50b3f42324652b9aabdf52e1 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Thu, 11 May 2023 22:54:03 -0700 Subject: [PATCH] Simplify reg_read/reg_write, obtaining a perf boost. Single reg_read/reg_write is now about 25% faster. --- include/uc_priv.h | 18 +- qemu/aarch64.h | 6 +- qemu/arm.h | 6 +- qemu/m68k.h | 6 +- qemu/mips.h | 6 +- qemu/mips64.h | 6 +- qemu/mips64el.h | 6 +- qemu/mipsel.h | 6 +- qemu/ppc.h | 6 +- qemu/ppc64.h | 6 +- qemu/riscv32.h | 6 +- qemu/riscv64.h | 6 +- qemu/s390x.h | 3 + qemu/sparc.h | 6 +- qemu/sparc64.h | 6 +- qemu/target/arm/unicorn.h | 33 +-- qemu/target/arm/unicorn_aarch64.c | 110 +------- qemu/target/arm/unicorn_arm.c | 101 ++------ qemu/target/i386/unicorn.c | 104 +------- qemu/target/i386/unicorn.h | 16 +- qemu/target/m68k/unicorn.c | 100 +------- qemu/target/m68k/unicorn.h | 16 +- qemu/target/mips/unicorn.c | 143 +---------- qemu/target/mips/unicorn.h | 47 ++-- qemu/target/ppc/unicorn.c | 122 ++------- qemu/target/ppc/unicorn.h | 27 +- qemu/target/riscv/unicorn.c | 117 +-------- qemu/target/riscv/unicorn.h | 29 +-- qemu/target/s390x/unicorn.c | 102 +------- qemu/target/s390x/unicorn.h | 16 +- qemu/target/sparc/unicorn.c | 100 +------- qemu/target/sparc/unicorn.h | 28 +-- qemu/target/sparc/unicorn64.c | 90 +------ qemu/target/tricore/unicorn.c | 99 ++------ qemu/target/tricore/unicorn.h | 19 +- qemu/tricore.h | 3 + qemu/unicorn_common.h | 8 +- qemu/x86_64.h | 6 +- symbols.sh | 27 +- uc.c | 404 ++++++++++++++++++++---------- 40 files changed, 563 insertions(+), 1403 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 5fbdda07..ef3d30e3 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -62,20 +62,14 @@ typedef struct _mmio_cbs { typedef uc_err (*query_t)(struct uc_struct *uc, uc_query_type type, size_t *result); -// return 0 on success, -1 on failure -typedef int (*reg_read_t)(struct uc_struct *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -typedef int (*reg_write_t)(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +typedef uc_err (*reg_read_t)(void *env, int mode, unsigned int regid, + void *value, size_t *size); +typedef uc_err (*reg_write_t)(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -typedef int (*context_reg_read_t)(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -typedef int (*context_reg_write_t)(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); typedef struct { - context_reg_read_t context_reg_read; - context_reg_write_t context_reg_write; + reg_read_t read; + reg_write_t write; } context_reg_rw_t; typedef void (*reg_reset_t)(struct uc_struct *uc); diff --git a/qemu/aarch64.h b/qemu/aarch64.h index c678501b..aba5a963 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _aarch64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_aarch64 +#define reg_read reg_read_aarch64 +#define reg_write reg_write_aarch64 +#define uc_init uc_init_aarch64 #define uc_add_inline_hook uc_add_inline_hook_aarch64 #define uc_del_inline_hook uc_del_inline_hook_aarch64 #define tb_invalidate_phys_range tb_invalidate_phys_range_aarch64 @@ -2959,9 +2962,6 @@ #define helper_frint32_d helper_frint32_d_aarch64 #define helper_frint64_d helper_frint64_d_aarch64 #define helper_check_hcr_el2_trap helper_check_hcr_el2_trap_aarch64 -#define arm64_reg_reset arm64_reg_reset_aarch64 -#define arm64_reg_read arm64_reg_read_aarch64 -#define arm64_reg_write arm64_reg_write_aarch64 #define mla_op mla_op_aarch64 #define mls_op mls_op_aarch64 #define sshl_op sshl_op_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index 13e8ffee..be8271c6 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _arm #endif #define unicorn_fill_tlb unicorn_fill_tlb_arm +#define reg_read reg_read_arm +#define reg_write reg_write_arm +#define uc_init uc_init_arm #define uc_add_inline_hook uc_add_inline_hook_arm #define uc_del_inline_hook uc_del_inline_hook_arm #define tb_invalidate_phys_range tb_invalidate_phys_range_arm @@ -1970,9 +1973,6 @@ #define helper_frint32_d helper_frint32_d_arm #define helper_frint64_d helper_frint64_d_arm #define helper_check_hcr_el2_trap helper_check_hcr_el2_trap_arm -#define arm_reg_reset arm_reg_reset_arm -#define arm_reg_read arm_reg_read_arm -#define arm_reg_write arm_reg_write_arm #define mla_op mla_op_arm #define mls_op mls_op_arm #define sshl_op sshl_op_arm diff --git a/qemu/m68k.h b/qemu/m68k.h index 23f5d93a..ab97771b 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _m68k #endif #define unicorn_fill_tlb unicorn_fill_tlb_m68k +#define reg_read reg_read_m68k +#define reg_write reg_write_m68k +#define uc_init uc_init_m68k #define uc_add_inline_hook uc_add_inline_hook_m68k #define uc_del_inline_hook uc_del_inline_hook_m68k #define tb_invalidate_phys_range tb_invalidate_phys_range_m68k @@ -1433,7 +1436,4 @@ #define register_m68k_insns register_m68k_insns_m68k #define gen_intermediate_code gen_intermediate_code_m68k #define restore_state_to_opc restore_state_to_opc_m68k -#define m68k_reg_reset m68k_reg_reset_m68k -#define m68k_reg_read m68k_reg_read_m68k -#define m68k_reg_write m68k_reg_write_m68k #endif diff --git a/qemu/mips.h b/qemu/mips.h index 8aaa4de4..95f0abda 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _mips #endif #define unicorn_fill_tlb unicorn_fill_tlb_mips +#define reg_read reg_read_mips +#define reg_write reg_write_mips +#define uc_init uc_init_mips #define uc_add_inline_hook uc_add_inline_hook_mips #define uc_del_inline_hook uc_del_inline_hook_mips #define tb_invalidate_phys_range tb_invalidate_phys_range_mips @@ -2385,9 +2388,6 @@ #define cpu_mips_realize_env cpu_mips_realize_env_mips #define cpu_state_reset cpu_state_reset_mips #define restore_state_to_opc restore_state_to_opc_mips -#define mips_reg_reset mips_reg_reset_mips -#define mips_reg_read mips_reg_read_mips -#define mips_reg_write mips_reg_write_mips #define ieee_rm ieee_rm_mips #define mips_defs mips_defs_mips #define mips_defs_number mips_defs_number_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 30f6b0ac..e29e20e5 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _mips64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_mips64 +#define reg_read reg_read_mips64 +#define reg_write reg_write_mips64 +#define uc_init uc_init_mips64 #define uc_add_inline_hook uc_add_inline_hook_mips64 #define uc_del_inline_hook uc_del_inline_hook_mips64 #define tb_invalidate_phys_range tb_invalidate_phys_range_mips64 @@ -2385,9 +2388,6 @@ #define cpu_mips_realize_env cpu_mips_realize_env_mips64 #define cpu_state_reset cpu_state_reset_mips64 #define restore_state_to_opc restore_state_to_opc_mips64 -#define mips_reg_reset mips_reg_reset_mips64 -#define mips_reg_read mips_reg_read_mips64 -#define mips_reg_write mips_reg_write_mips64 #define ieee_rm ieee_rm_mips64 #define mips_defs mips_defs_mips64 #define mips_defs_number mips_defs_number_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 115aa427..6f94f431 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _mips64el #endif #define unicorn_fill_tlb unicorn_fill_tlb_mips64el +#define reg_read reg_read_mips64el +#define reg_write reg_write_mips64el +#define uc_init uc_init_mips64el #define uc_add_inline_hook uc_add_inline_hook_mips64el #define uc_del_inline_hook uc_del_inline_hook_mips64el #define tb_invalidate_phys_range tb_invalidate_phys_range_mips64el @@ -2385,9 +2388,6 @@ #define cpu_mips_realize_env cpu_mips_realize_env_mips64el #define cpu_state_reset cpu_state_reset_mips64el #define restore_state_to_opc restore_state_to_opc_mips64el -#define mips_reg_reset mips_reg_reset_mips64el -#define mips_reg_read mips_reg_read_mips64el -#define mips_reg_write mips_reg_write_mips64el #define ieee_rm ieee_rm_mips64el #define mips_defs mips_defs_mips64el #define mips_defs_number mips_defs_number_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 552c968e..1b313d4b 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _mipsel #endif #define unicorn_fill_tlb unicorn_fill_tlb_mipsel +#define reg_read reg_read_mipsel +#define reg_write reg_write_mipsel +#define uc_init uc_init_mipsel #define uc_add_inline_hook uc_add_inline_hook_mipsel #define uc_del_inline_hook uc_del_inline_hook_mipsel #define tb_invalidate_phys_range tb_invalidate_phys_range_mipsel @@ -2385,9 +2388,6 @@ #define cpu_mips_realize_env cpu_mips_realize_env_mipsel #define cpu_state_reset cpu_state_reset_mipsel #define restore_state_to_opc restore_state_to_opc_mipsel -#define mips_reg_reset mips_reg_reset_mipsel -#define mips_reg_read mips_reg_read_mipsel -#define mips_reg_write mips_reg_write_mipsel #define ieee_rm ieee_rm_mipsel #define mips_defs mips_defs_mipsel #define mips_defs_number mips_defs_number_mipsel diff --git a/qemu/ppc.h b/qemu/ppc.h index 67e3c4b9..a3a339fb 100644 --- a/qemu/ppc.h +++ b/qemu/ppc.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _ppc #endif #define unicorn_fill_tlb unicorn_fill_tlb_ppc +#define reg_read reg_read_ppc +#define reg_write reg_write_ppc +#define uc_init uc_init_ppc #define uc_add_inline_hook uc_add_inline_hook_ppc #define uc_del_inline_hook uc_del_inline_hook_ppc #define tb_invalidate_phys_range tb_invalidate_phys_range_ppc @@ -1280,9 +1283,6 @@ #define gen_helper_cpsr_write gen_helper_cpsr_write_ppc #define ppc_cpu_unrealize ppc_cpu_unrealize_ppc #define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc -#define ppc_reg_reset ppc_reg_reset_ppc -#define ppc_reg_read ppc_reg_read_ppc -#define ppc_reg_write ppc_reg_write_ppc #define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc #define ppc_cpu_do_system_reset ppc_cpu_do_system_reset_ppc #define ppc_cpu_do_fwnmi_machine_check ppc_cpu_do_fwnmi_machine_check_ppc diff --git a/qemu/ppc64.h b/qemu/ppc64.h index 36ffbc64..04564484 100644 --- a/qemu/ppc64.h +++ b/qemu/ppc64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _ppc64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_ppc64 +#define reg_read reg_read_ppc64 +#define reg_write reg_write_ppc64 +#define uc_init uc_init_ppc64 #define uc_add_inline_hook uc_add_inline_hook_ppc64 #define uc_del_inline_hook uc_del_inline_hook_ppc64 #define tb_invalidate_phys_range tb_invalidate_phys_range_ppc64 @@ -1280,9 +1283,6 @@ #define gen_helper_cpsr_write gen_helper_cpsr_write_ppc64 #define ppc_cpu_unrealize ppc_cpu_unrealize_ppc64 #define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc64 -#define ppc_reg_reset ppc_reg_reset_ppc64 -#define ppc_reg_read ppc_reg_read_ppc64 -#define ppc_reg_write ppc_reg_write_ppc64 #define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc64 #define ppc_cpu_do_system_reset ppc_cpu_do_system_reset_ppc64 #define ppc_cpu_do_fwnmi_machine_check ppc_cpu_do_fwnmi_machine_check_ppc64 diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 94a8fc02..a7a91fa7 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _riscv32 #endif #define unicorn_fill_tlb unicorn_fill_tlb_riscv32 +#define reg_read reg_read_riscv32 +#define reg_write reg_write_riscv32 +#define uc_init uc_init_riscv32 #define uc_add_inline_hook uc_add_inline_hook_riscv32 #define uc_del_inline_hook uc_del_inline_hook_riscv32 #define tb_invalidate_phys_range tb_invalidate_phys_range_riscv32 @@ -1361,9 +1364,6 @@ #define riscv_translate_init riscv_translate_init_riscv32 #define restore_state_to_opc restore_state_to_opc_riscv32 #define cpu_riscv_init cpu_riscv_init_riscv32 -#define riscv_reg_reset riscv_reg_reset_riscv32 -#define riscv_reg_read riscv_reg_read_riscv32 -#define riscv_reg_write riscv_reg_write_riscv32 #define helper_fcvt_l_s helper_fcvt_l_s_riscv32 #define helper_fcvt_lu_s helper_fcvt_lu_s_riscv32 #define helper_fcvt_s_l helper_fcvt_s_l_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index bfc0bff4..6934d749 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _riscv64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_riscv64 +#define reg_read reg_read_riscv64 +#define reg_write reg_write_riscv64 +#define uc_init uc_init_riscv64 #define uc_add_inline_hook uc_add_inline_hook_riscv64 #define uc_del_inline_hook uc_del_inline_hook_riscv64 #define tb_invalidate_phys_range tb_invalidate_phys_range_riscv64 @@ -1361,9 +1364,6 @@ #define riscv_translate_init riscv_translate_init_riscv64 #define restore_state_to_opc restore_state_to_opc_riscv64 #define cpu_riscv_init cpu_riscv_init_riscv64 -#define riscv_reg_reset riscv_reg_reset_riscv64 -#define riscv_reg_read riscv_reg_read_riscv64 -#define riscv_reg_write riscv_reg_write_riscv64 #define helper_fcvt_l_s helper_fcvt_l_s_riscv64 #define helper_fcvt_lu_s helper_fcvt_lu_s_riscv64 #define helper_fcvt_s_l helper_fcvt_s_l_riscv64 diff --git a/qemu/s390x.h b/qemu/s390x.h index b4295cbc..e00bcae9 100644 --- a/qemu/s390x.h +++ b/qemu/s390x.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _s390x #endif #define unicorn_fill_tlb unicorn_fill_tlb_s390x +#define reg_read reg_read_s390x +#define reg_write reg_write_s390x +#define uc_init uc_init_s390x #define uc_add_inline_hook uc_add_inline_hook_s390x #define uc_del_inline_hook uc_del_inline_hook_s390x #define tb_invalidate_phys_range tb_invalidate_phys_range_s390x diff --git a/qemu/sparc.h b/qemu/sparc.h index 7083a74f..596d8328 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _sparc #endif #define unicorn_fill_tlb unicorn_fill_tlb_sparc +#define reg_read reg_read_sparc +#define reg_write reg_write_sparc +#define uc_init uc_init_sparc #define uc_add_inline_hook uc_add_inline_hook_sparc #define uc_del_inline_hook uc_del_inline_hook_sparc #define tb_invalidate_phys_range tb_invalidate_phys_range_sparc @@ -1415,7 +1418,4 @@ #define helper_wrpil helper_wrpil_sparc #define helper_done helper_done_sparc #define helper_retry helper_retry_sparc -#define sparc_reg_reset sparc_reg_reset_sparc -#define sparc_reg_read sparc_reg_read_sparc -#define sparc_reg_write sparc_reg_write_sparc #endif diff --git a/qemu/sparc64.h b/qemu/sparc64.h index e70362dc..223832ee 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _sparc64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_sparc64 +#define reg_read reg_read_sparc64 +#define reg_write reg_write_sparc64 +#define uc_init uc_init_sparc64 #define uc_add_inline_hook uc_add_inline_hook_sparc64 #define uc_del_inline_hook uc_del_inline_hook_sparc64 #define tb_invalidate_phys_range tb_invalidate_phys_range_sparc64 @@ -1415,7 +1418,4 @@ #define helper_wrpil helper_wrpil_sparc64 #define helper_done helper_done_sparc64 #define helper_retry helper_retry_sparc64 -#define sparc_reg_reset sparc_reg_reset_sparc64 -#define sparc_reg_read sparc_reg_read_sparc64 -#define sparc_reg_write sparc_reg_write_sparc64 #endif diff --git a/qemu/target/arm/unicorn.h b/qemu/target/arm/unicorn.h index 18612489..9327f04f 100644 --- a/qemu/target/arm/unicorn.h +++ b/qemu/target/arm/unicorn.h @@ -5,28 +5,15 @@ #define UC_QEMU_TARGET_ARM_H // functions to read & write registers -int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int arm_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_arm(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_aarch64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_arm(void *env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc); +uc_err reg_write_aarch64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); - -void arm_reg_reset(struct uc_struct *uc); -void arm64_reg_reset(struct uc_struct *uc); - -void arm_uc_init(struct uc_struct *uc); - -void arm64_uc_init(struct uc_struct *uc); +void uc_init_arm(struct uc_struct *uc); +void uc_init_aarch64(struct uc_struct *uc); #endif diff --git a/qemu/target/arm/unicorn_aarch64.c b/qemu/target/arm/unicorn_aarch64.c index 06320819..c2463957 100644 --- a/qemu/target/arm/unicorn_aarch64.c +++ b/qemu/target/arm/unicorn_aarch64.c @@ -88,7 +88,7 @@ static void arm64_release(void *ctx) g_hash_table_destroy(cpu->cp_regs); } -void arm64_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; memset(env->xregs, 0, sizeof(env->xregs)); @@ -138,9 +138,11 @@ static uc_err write_cp_reg(CPUARMState *env, uc_arm64_cp_reg *cp) return UC_ERR_OK; } -static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUARMState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) { @@ -267,9 +269,11 @@ static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, - size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUARMState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) { @@ -398,94 +402,6 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, return ret; } -static uc_err reg_read_batch(CPUARMState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUARMState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUARMState *env = &(ARM_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUARMState *env = &(ARM_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -#ifdef TARGET_WORDS_BIGENDIAN -int arm64eb_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#else -int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#endif -{ - CPUARMState *env = (CPUARMState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -#ifdef TARGET_WORDS_BIGENDIAN -int arm64eb_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#else -int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#endif -{ - CPUARMState *env = (CPUARMState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int arm64_cpus_init(struct uc_struct *uc, const char *cpu_model) { ARMCPU *cpu; @@ -499,11 +415,11 @@ static int arm64_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void arm64_uc_init(struct uc_struct *uc) +void uc_init(struct uc_struct *uc) { - uc->reg_read = arm64_reg_read; - uc->reg_write = arm64_reg_write; - uc->reg_reset = arm64_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = arm64_set_pc; uc->get_pc = arm64_get_pc; uc->release = arm64_release; diff --git a/qemu/target/arm/unicorn_arm.c b/qemu/target/arm/unicorn_arm.c index 3582532e..f50ac0e1 100644 --- a/qemu/target/arm/unicorn_arm.c +++ b/qemu/target/arm/unicorn_arm.c @@ -91,7 +91,7 @@ static void arm_release(void *ctx) g_hash_table_destroy(cpu->cp_regs); } -void arm_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env; (void)uc; @@ -206,9 +206,11 @@ static uc_err write_cp_reg(CPUARMState *env, uc_arm_cp_reg *cp) return UC_ERR_OK; } -static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUARMState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM_REG_R0 && regid <= UC_ARM_REG_R12) { @@ -354,9 +356,11 @@ static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, - size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUARMState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM_REG_R0 && regid <= UC_ARM_REG_R12) { @@ -551,84 +555,6 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, return ret; } -static uc_err reg_read_batch(CPUARMState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUARMState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUARMState *env = &(ARM_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int arm_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUArchState *env = &(ARM_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUARMState *env = (CPUARMState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUARMState *env = (CPUARMState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static bool arm_stop_interrupt(struct uc_struct *uc, int intno) { switch (intno) { @@ -827,11 +753,12 @@ static uc_err uc_arm_context_restore(struct uc_struct *uc, uc_context *context) return UC_ERR_OK; } -void arm_uc_init(struct uc_struct *uc) +DEFAULT_VISIBILITY +void uc_init(struct uc_struct *uc) { - uc->reg_read = arm_reg_read; - uc->reg_write = arm_reg_write; - uc->reg_reset = arm_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = arm_set_pc; uc->get_pc = arm_get_pc; uc->stop_interrupt = arm_stop_interrupt; diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index 6da03f2a..ceddb55d 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -65,7 +65,7 @@ static void x86_release(void *ctx) free(xcc->model); } -void x86_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; @@ -211,9 +211,11 @@ static int x86_msr_write(CPUX86State *env, uc_x86_msr *msr) return 0; } -static uc_err reg_read(CPUX86State *env, unsigned int regid, void *value, - size_t *size, uc_mode mode) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUX86State *env = _env; uc_err ret = UC_ERR_ARG; switch (regid) { @@ -989,9 +991,11 @@ static uc_err reg_read(CPUX86State *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value, - size_t *size, uc_mode mode, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUX86State *env = _env; uc_err ret = UC_ERR_ARG; switch (regid) { @@ -1806,88 +1810,6 @@ static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value, return ret; } -static uc_err reg_read_batch(CPUX86State *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count, - int mode) -{ - int i; - uc_err err; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - err = reg_read(env, regid, value, sizes ? sizes + i : NULL, mode); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUX86State *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int mode, int *setpc) -{ - int i; - uc_err err; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, mode, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUX86State *env = &(X86_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count, uc->mode); -} - -int x86_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUX86State *env = &(X86_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = - reg_write_batch(env, regs, vals, sizes, count, uc->mode, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int x86_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUX86State *env = (CPUX86State *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count, ctx->mode); -} - -DEFAULT_VISIBILITY -int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUX86State *env = (CPUX86State *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, ctx->mode, &setpc); -} - static bool x86_stop_interrupt(struct uc_struct *uc, int intno) { switch (intno) { @@ -1945,11 +1867,11 @@ static int x86_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void x86_uc_init(struct uc_struct *uc) +void uc_init(struct uc_struct *uc) { - uc->reg_read = x86_reg_read; - uc->reg_write = x86_reg_write; - uc->reg_reset = x86_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->release = x86_release; uc->set_pc = x86_set_pc; uc->get_pc = x86_get_pc; diff --git a/qemu/target/i386/unicorn.h b/qemu/target/i386/unicorn.h index fe5688ad..9927b6c9 100644 --- a/qemu/target/i386/unicorn.h +++ b/qemu/target/i386/unicorn.h @@ -6,16 +6,10 @@ #define UC_QEMU_TARGET_I386_H // functions to read & write registers -int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int x86_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int x86_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_x86_64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_x86_64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -void x86_reg_reset(struct uc_struct *uc); - -void x86_uc_init(struct uc_struct *uc); +void uc_init_x86_64(struct uc_struct *uc); #endif diff --git a/qemu/target/m68k/unicorn.c b/qemu/target/m68k/unicorn.c index 93bc7170..f1efd66e 100644 --- a/qemu/target/m68k/unicorn.c +++ b/qemu/target/m68k/unicorn.c @@ -39,7 +39,7 @@ static void m68k_release(void *ctx) } } -void m68k_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; @@ -49,9 +49,11 @@ void m68k_reg_reset(struct uc_struct *uc) env->pc = 0; } -static uc_err reg_read(CPUM68KState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUM68KState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) { @@ -78,9 +80,11 @@ static uc_err reg_read(CPUM68KState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUM68KState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUM68KState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) { @@ -108,84 +112,6 @@ static uc_err reg_write(CPUM68KState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPUM68KState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUM68KState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUM68KState *env = &(M68K_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUM68KState *env = &(M68K_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int m68k_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUM68KState *env = (CPUM68KState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUM68KState *env = (CPUM68KState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int m68k_cpus_init(struct uc_struct *uc, const char *cpu_model) { M68kCPU *cpu; @@ -198,12 +124,12 @@ static int m68k_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void m68k_uc_init(struct uc_struct *uc) +void uc_init(struct uc_struct *uc) { uc->release = m68k_release; - uc->reg_read = m68k_reg_read; - uc->reg_write = m68k_reg_write; - uc->reg_reset = m68k_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = m68k_set_pc; uc->get_pc = m68k_get_pc; uc->cpus_init = m68k_cpus_init; diff --git a/qemu/target/m68k/unicorn.h b/qemu/target/m68k/unicorn.h index 463cfd33..c81ad48e 100644 --- a/qemu/target/m68k/unicorn.h +++ b/qemu/target/m68k/unicorn.h @@ -5,16 +5,10 @@ #define UC_QEMU_TARGET_M68K_H // functions to read & write registers -int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int m68k_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_m68k(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_m68k(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -void m68k_reg_reset(struct uc_struct *uc); - -void m68k_uc_init(struct uc_struct *uc); +void uc_init_m68k(struct uc_struct *uc); #endif diff --git a/qemu/target/mips/unicorn.c b/qemu/target/mips/unicorn.c index 4edb7d33..77a7d48d 100644 --- a/qemu/target/mips/unicorn.c +++ b/qemu/target/mips/unicorn.c @@ -49,7 +49,7 @@ static void mips_release(void *ctx) g_free(cpu->env.tlb); } -void mips_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env; (void)uc; @@ -59,9 +59,11 @@ void mips_reg_reset(struct uc_struct *uc) env->active_tc.PC = 0; } -static uc_err reg_read(CPUMIPSState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUMIPSState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) { @@ -101,9 +103,11 @@ static uc_err reg_read(CPUMIPSState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUMIPSState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUMIPSState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) { @@ -148,115 +152,6 @@ static uc_err reg_write(CPUMIPSState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPUMIPSState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUMIPSState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUMIPSState *env = &(MIPS_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int mips_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUMIPSState *env = &(MIPS_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -#ifdef TARGET_MIPS64 -#ifdef TARGET_WORDS_BIGENDIAN -int mips64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#else -int mips64el_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#endif -#else // if TARGET_MIPS -#ifdef TARGET_WORDS_BIGENDIAN -int mips_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#else -int mipsel_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#endif -#endif -{ - CPUMIPSState *env = (CPUMIPSState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -#ifdef TARGET_MIPS64 -#ifdef TARGET_WORDS_BIGENDIAN -int mips64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#else -int mips64el_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count) -#endif -#else // if TARGET_MIPS -#ifdef TARGET_WORDS_BIGENDIAN -int mips_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#else -int mipsel_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#endif -#endif -{ - CPUMIPSState *env = (CPUMIPSState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int mips_cpus_init(struct uc_struct *uc, const char *cpu_model) { MIPSCPU *cpu; @@ -270,23 +165,11 @@ static int mips_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -#ifdef TARGET_MIPS64 -#ifdef TARGET_WORDS_BIGENDIAN -void mips64_uc_init(struct uc_struct *uc) -#else -void mips64el_uc_init(struct uc_struct *uc) -#endif -#else // if TARGET_MIPS -#ifdef TARGET_WORDS_BIGENDIAN -void mips_uc_init(struct uc_struct *uc) -#else -void mipsel_uc_init(struct uc_struct *uc) -#endif -#endif +void uc_init(struct uc_struct *uc) { - uc->reg_read = mips_reg_read; - uc->reg_write = mips_reg_write; - uc->reg_reset = mips_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->release = mips_release; uc->set_pc = mips_set_pc; uc->get_pc = mips_get_pc; diff --git a/qemu/target/mips/unicorn.h b/qemu/target/mips/unicorn.h index caaa414c..f089e5df 100644 --- a/qemu/target/mips/unicorn.h +++ b/qemu/target/mips/unicorn.h @@ -5,33 +5,26 @@ #define UC_QEMU_TARGET_MIPS_H // functions to read & write registers -int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int mips_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_mips(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_mipsel(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_mips64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_mips64el(void *env, int mode, unsigned int regid, void *value, + size_t *size); -int mips_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int mips_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int mipsel_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int mipsel_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int mips64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int mips64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int mips64el_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int mips64el_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); +uc_err reg_write_mips(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +uc_err reg_write_mipsel(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +uc_err reg_write_mips64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +uc_err reg_write_mips64el(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -void mips_reg_reset(struct uc_struct *uc); - -void mips_uc_init(struct uc_struct *uc); -void mipsel_uc_init(struct uc_struct *uc); -void mips64_uc_init(struct uc_struct *uc); -void mips64el_uc_init(struct uc_struct *uc); +void uc_init_mips(struct uc_struct *uc); +void uc_init_mipsel(struct uc_struct *uc); +void uc_init_mips64(struct uc_struct *uc); +void uc_init_mips64el(struct uc_struct *uc); #endif diff --git a/qemu/target/ppc/unicorn.c b/qemu/target/ppc/unicorn.c index edda420b..ce86cf93 100644 --- a/qemu/target/ppc/unicorn.c +++ b/qemu/target/ppc/unicorn.c @@ -136,7 +136,7 @@ static void ppc_release(void *ctx) ppc_cpu_unrealize(tcg_ctx->uc->cpu); } -void ppc_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env; env = uc->cpu->env_ptr; @@ -146,9 +146,11 @@ void ppc_reg_reset(struct uc_struct *uc) } // http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Motorola_PowerPC/PowerPc/GenInfo/pemch2.pdf -static uc_err reg_read(CPUPPCState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUPPCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) { @@ -170,9 +172,9 @@ static uc_err reg_read(CPUPPCState *env, unsigned int regid, void *value, break; case UC_PPC_REG_CR: { CHECK_REG_TYPE(uint32_t); - uint32_t val; - val = 0; - for (int i = 0; i < 8; i++) { + int i; + uint32_t val = 0; + for (i = 0; i < 8; i++) { val <<= 4; val |= env->crf[i]; } @@ -205,10 +207,11 @@ static uc_err reg_read(CPUPPCState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value, - size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { - int i; + CPUPPCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) { @@ -231,6 +234,7 @@ static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value, break; case UC_PPC_REG_CR: { CHECK_REG_TYPE(uint32_t); + int i; uint32_t val = *(uint32_t *)value; for (i = 7; i >= 0; i--) { env->crf[i] = val & 0b1111; @@ -264,94 +268,6 @@ static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value, return ret; } -static uc_err reg_read_batch(CPUPPCState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUPPCState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUPPCState *env = &(POWERPC_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUPPCState *env = &(POWERPC_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -#ifdef TARGET_PPC64 -int ppc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#else -int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#endif -{ - CPUPPCState *env = (CPUPPCState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -#ifdef TARGET_PPC64 -int ppc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#else -int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#endif -{ - CPUPPCState *env = (CPUPPCState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - PowerPCCPU *cpu_ppc_init(struct uc_struct *uc); static int ppc_cpus_init(struct uc_struct *uc, const char *cpu_model) { @@ -365,15 +281,11 @@ static int ppc_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -#ifdef TARGET_PPC64 -void ppc64_uc_init(struct uc_struct *uc) -#else -void ppc_uc_init(struct uc_struct *uc) -#endif +void uc_init(struct uc_struct *uc) { - uc->reg_read = ppc_reg_read; - uc->reg_write = ppc_reg_write; - uc->reg_reset = ppc_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->release = ppc_release; uc->set_pc = ppc_set_pc; uc->get_pc = ppc_get_pc; diff --git a/qemu/target/ppc/unicorn.h b/qemu/target/ppc/unicorn.h index df1d901f..d6d47ad7 100644 --- a/qemu/target/ppc/unicorn.h +++ b/qemu/target/ppc/unicorn.h @@ -5,22 +5,15 @@ #define UC_QEMU_TARGET_PPC_H // functions to read & write registers -int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_ppc(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_ppc64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_ppc(void *env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc); +uc_err reg_write_ppc64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int ppc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int ppc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); - -void ppc_reg_reset(struct uc_struct *uc); - -void ppc_uc_init(struct uc_struct *uc); -void ppc64_uc_init(struct uc_struct *uc); +void uc_init_ppc(struct uc_struct *uc); +void uc_init_ppc64(struct uc_struct *uc); #endif diff --git a/qemu/target/riscv/unicorn.c b/qemu/target/riscv/unicorn.c index 86ab8746..8b55282f 100644 --- a/qemu/target/riscv/unicorn.c +++ b/qemu/target/riscv/unicorn.c @@ -77,11 +77,13 @@ static void riscv_release(void *ctx) } } -void riscv_reg_reset(struct uc_struct *uc) {} +static void reg_reset(struct uc_struct *uc) {} -static uc_err reg_read(CPURISCVState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPURISCVState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_RISCV_REG_X0 && regid <= UC_RISCV_REG_X31) { @@ -127,9 +129,11 @@ static uc_err reg_read(CPURISCVState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPURISCVState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPURISCVState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_RISCV_REG_X0 && regid <= UC_RISCV_REG_X31) { @@ -175,96 +179,6 @@ static uc_err reg_write(CPURISCVState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPURISCVState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPURISCVState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPURISCVState *env = &(RISCV_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPURISCVState *env = &(RISCV_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -#ifdef TARGET_RISCV32 -int riscv32_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#else -/* TARGET_RISCV64 */ -int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -#endif -{ - CPURISCVState *env = (CPURISCVState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -#ifdef TARGET_RISCV32 -int riscv32_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#else -/* TARGET_RISCV64 */ -int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -#endif -{ - CPURISCVState *env = (CPURISCVState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static bool riscv_stop_interrupt(struct uc_struct *uc, int intno) { // detect stop exception @@ -298,16 +212,11 @@ static int riscv_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -#ifdef TARGET_RISCV32 -void riscv32_uc_init(struct uc_struct *uc) -#else -/* TARGET_RISCV64 */ -void riscv64_uc_init(struct uc_struct *uc) -#endif +void uc_init(struct uc_struct *uc) { - uc->reg_read = riscv_reg_read; - uc->reg_write = riscv_reg_write; - uc->reg_reset = riscv_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->release = riscv_release; uc->set_pc = riscv_set_pc; uc->get_pc = riscv_get_pc; diff --git a/qemu/target/riscv/unicorn.h b/qemu/target/riscv/unicorn.h index c7eeb450..87cdb3f8 100644 --- a/qemu/target/riscv/unicorn.h +++ b/qemu/target/riscv/unicorn.h @@ -6,24 +6,15 @@ #define UC_QEMU_TARGET_RISCV_H // functions to read & write registers -int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_riscv32(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_riscv64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_riscv32(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +uc_err reg_write_riscv64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -int riscv32_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int riscv32_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); -int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); - -void riscv_reg_reset(struct uc_struct *uc); - -void riscv32_uc_init(struct uc_struct *uc); -void riscv64_uc_init(struct uc_struct *uc); +void uc_init_riscv32(struct uc_struct *uc); +void uc_init_riscv64(struct uc_struct *uc); #endif diff --git a/qemu/target/s390x/unicorn.c b/qemu/target/s390x/unicorn.c index 9d4ac0b0..972bf9e3 100644 --- a/qemu/target/s390x/unicorn.c +++ b/qemu/target/s390x/unicorn.c @@ -43,7 +43,7 @@ static void s390_release(void *ctx) // TODO: Anymore to free? } -void s390_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; @@ -53,9 +53,11 @@ void s390_reg_reset(struct uc_struct *uc) env->psw.addr = 0; } -static uc_err reg_read(CPUS390XState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUS390XState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_S390X_REG_R0 && regid <= UC_S390X_REG_R15) { @@ -82,9 +84,11 @@ static uc_err reg_read(CPUS390XState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUS390XState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUS390XState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_S390X_REG_R0 && regid <= UC_S390X_REG_R15) { @@ -112,86 +116,6 @@ static uc_err reg_write(CPUS390XState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPUS390XState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUS390XState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUS390XState *env = &(S390_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int s390_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUS390XState *env = &(S390_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int s390_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUS390XState *env = (CPUS390XState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUS390XState *env = (CPUS390XState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int s390_cpus_init(struct uc_struct *uc, const char *cpu_model) { S390CPU *cpu; @@ -204,12 +128,12 @@ static int s390_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void s390_uc_init(struct uc_struct *uc) +void uc_init(struct uc_struct *uc) { uc->release = s390_release; - uc->reg_read = s390_reg_read; - uc->reg_write = s390_reg_write; - uc->reg_reset = s390_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = s390_set_pc; uc->get_pc = s390_get_pc; uc->cpus_init = s390_cpus_init; diff --git a/qemu/target/s390x/unicorn.h b/qemu/target/s390x/unicorn.h index 50d507e6..96285f7f 100644 --- a/qemu/target/s390x/unicorn.h +++ b/qemu/target/s390x/unicorn.h @@ -5,16 +5,10 @@ #define UC_QEMU_TARGET_S390X_H // functions to read & write registers -int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int s390_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int s390_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_s390x(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_s390x(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -void s390_reg_reset(struct uc_struct *uc); - -void s390_uc_init(struct uc_struct *uc); +void uc_init_s390x(struct uc_struct *uc); #endif diff --git a/qemu/target/sparc/unicorn.c b/qemu/target/sparc/unicorn.c index 030d3b12..39c78b68 100644 --- a/qemu/target/sparc/unicorn.c +++ b/qemu/target/sparc/unicorn.c @@ -48,7 +48,7 @@ static void sparc_release(void *ctx) } } -void sparc_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; @@ -61,9 +61,11 @@ void sparc_reg_reset(struct uc_struct *uc) env->regwptr = env->regbase; } -static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUSPARCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { @@ -91,9 +93,11 @@ static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUSPARCState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUSPARCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { @@ -124,84 +128,6 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPUSPARCState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUSPARCState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count) -{ - CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = (CPUSPARCState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = (CPUSPARCState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) { SPARCCPU *cpu; @@ -214,12 +140,12 @@ static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void sparc_uc_init(struct uc_struct *uc) +void uc_init(struct uc_struct *uc) { uc->release = sparc_release; - uc->reg_read = sparc_reg_read; - uc->reg_write = sparc_reg_write; - uc->reg_reset = sparc_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = sparc_set_pc; uc->get_pc = sparc_get_pc; uc->stop_interrupt = sparc_stop_interrupt; diff --git a/qemu/target/sparc/unicorn.h b/qemu/target/sparc/unicorn.h index 62c82ba2..4fbd6913 100644 --- a/qemu/target/sparc/unicorn.h +++ b/qemu/target/sparc/unicorn.h @@ -5,23 +5,15 @@ #define UC_QEMU_TARGET_SPARC_H // functions to read & write registers -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, - size_t *sizes, int count); -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); +uc_err reg_read_sparc(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_read_sparc64(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_sparc(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +uc_err reg_write_sparc64(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); -int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); -int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); - -void sparc_reg_reset(struct uc_struct *uc); - -void sparc_uc_init(struct uc_struct *uc); -void sparc64_uc_init(struct uc_struct *uc); +void uc_init_sparc(struct uc_struct *uc); +void uc_init_sparc64(struct uc_struct *uc); #endif diff --git a/qemu/target/sparc/unicorn64.c b/qemu/target/sparc/unicorn64.c index 6c7bfae9..11c46c8b 100644 --- a/qemu/target/sparc/unicorn64.c +++ b/qemu/target/sparc/unicorn64.c @@ -70,7 +70,7 @@ static void sparc_release(void *ctx) #endif } -void sparc_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; @@ -83,8 +83,11 @@ void sparc_reg_reset(struct uc_struct *uc) env->regwptr = env->regbase; } -static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUSPARCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { @@ -113,8 +116,11 @@ static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, size return ret; } -static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUSPARCState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { @@ -145,76 +151,6 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *valu return ret; } -static uc_err reg_read_batch(CPUSPARCState *env, unsigned int *regs, void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUSPARCState *env, unsigned int *regs, const void* const* vals, size_t *sizes, int count, int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, const void* const* vals, size_t *sizes, int count) -{ - CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -DEFAULT_VISIBILITY -int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = (CPUSPARCState *)ctx->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -DEFAULT_VISIBILITY -int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, const void *const *vals, size_t *sizes, int count) -{ - CPUSPARCState *env = (CPUSPARCState *)ctx->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) { SPARCCPU *cpu; @@ -227,12 +163,12 @@ static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) } DEFAULT_VISIBILITY -void sparc64_uc_init(struct uc_struct* uc) +void uc_init(struct uc_struct *uc) { uc->release = sparc_release; - uc->reg_read = sparc_reg_read; - uc->reg_write = sparc_reg_write; - uc->reg_reset = sparc_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = sparc_set_pc; uc->get_pc = sparc_get_pc; uc->stop_interrupt = sparc_stop_interrupt; diff --git a/qemu/target/tricore/unicorn.c b/qemu/target/tricore/unicorn.c index 3d35846b..9f47a7db 100644 --- a/qemu/target/tricore/unicorn.c +++ b/qemu/target/tricore/unicorn.c @@ -27,7 +27,7 @@ static uint64_t tricore_get_pc(struct uc_struct *uc) return ((CPUTriCoreState *)uc->cpu->env_ptr)->PC; } -void tricore_reg_reset(struct uc_struct *uc) +static void reg_reset(struct uc_struct *uc) { CPUTriCoreState *env; (void)uc; @@ -39,9 +39,11 @@ void tricore_reg_reset(struct uc_struct *uc) env->PC = 0; } -static uc_err reg_read(CPUTriCoreState *env, unsigned int regid, void *value, - size_t *size) +DEFAULT_VISIBILITY +uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, + size_t *size) { + CPUTriCoreState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) { @@ -139,9 +141,11 @@ static uc_err reg_read(CPUTriCoreState *env, unsigned int regid, void *value, return ret; } -static uc_err reg_write(CPUTriCoreState *env, unsigned int regid, - const void *value, size_t *size, int *setpc) +DEFAULT_VISIBILITY +uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc) { + CPUTriCoreState *env = _env; uc_err ret = UC_ERR_ARG; if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) { @@ -240,82 +244,6 @@ static uc_err reg_write(CPUTriCoreState *env, unsigned int regid, return ret; } -static uc_err reg_read_batch(CPUTriCoreState *env, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - void *value = vals[i]; - uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -static uc_err reg_write_batch(CPUTriCoreState *env, unsigned int *regs, - const void *const *vals, size_t *sizes, int count, - int *setpc) -{ - int i; - - for (i = 0; i < count; i++) { - unsigned int regid = regs[i]; - const void *value = vals[i]; - uc_err err = - reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc); - if (err) { - return err; - } - } - - return UC_ERR_OK; -} - -int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env); - return reg_read_batch(env, regs, vals, sizes, count); -} - -int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env); - int setpc = 0; - uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc); - if (err) { - return err; - } - if (setpc) { - // force to quit execution and flush TB - uc->quit_request = true; - break_translation_loop(uc); - } - - return UC_ERR_OK; -} - -int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count) -{ - CPUTriCoreState *env = (CPUTriCoreState *)uc->data; - return reg_read_batch(env, regs, vals, sizes, count); -} - -int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) -{ - CPUTriCoreState *env = (CPUTriCoreState *)uc->data; - int setpc = 0; - return reg_write_batch(env, regs, vals, sizes, count, &setpc); -} - static int tricore_cpus_init(struct uc_struct *uc, const char *cpu_model) { TriCoreCPU *cpu; @@ -347,11 +275,12 @@ static void tricore_release(void *ctx) } } -void tricore_uc_init(struct uc_struct *uc) +DEFAULT_VISIBILITY +void uc_init(struct uc_struct *uc) { - uc->reg_read = tricore_reg_read; - uc->reg_write = tricore_reg_write; - uc->reg_reset = tricore_reg_reset; + uc->reg_read = reg_read; + uc->reg_write = reg_write; + uc->reg_reset = reg_reset; uc->set_pc = tricore_set_pc; uc->get_pc = tricore_get_pc; uc->cpus_init = tricore_cpus_init; diff --git a/qemu/target/tricore/unicorn.h b/qemu/target/tricore/unicorn.h index e298da05..2958c365 100644 --- a/qemu/target/tricore/unicorn.h +++ b/qemu/target/tricore/unicorn.h @@ -10,19 +10,10 @@ #define UC_QEMU_TARGET_TRICORE_H // functions to read & write registers -int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count); - -int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count); -int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, - int count); - -void tricore_reg_reset(struct uc_struct *uc); - -void tricore_uc_init(struct uc_struct *uc); +uc_err reg_read_tricore(void *env, int mode, unsigned int regid, void *value, + size_t *size); +uc_err reg_write_tricore(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc); +void uc_init_tricore(struct uc_struct *uc); #endif diff --git a/qemu/tricore.h b/qemu/tricore.h index a7219654..a953ce0b 100644 --- a/qemu/tricore.h +++ b/qemu/tricore.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _tricore #endif #define unicorn_fill_tlb unicorn_fill_tlb_tricore +#define reg_read reg_read_tricore +#define reg_write reg_write_tricore +#define uc_init uc_init_tricore #define uc_add_inline_hook uc_add_inline_hook_tricore #define uc_del_inline_hook uc_del_inline_hook_tricore #define tb_invalidate_phys_range tb_invalidate_phys_range_tricore diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 3059eb74..035fe061 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -130,12 +130,10 @@ static inline void uc_common_init(struct uc_struct* uc) } #define CHECK_REG_TYPE(type) do { \ - if (unlikely(size)) { \ - if (unlikely(*size < sizeof(type))) { \ - return UC_ERR_NOMEM; \ - } \ - *size = sizeof(type); \ + if (unlikely(*size < sizeof(type))) { \ + return UC_ERR_NOMEM; \ } \ + *size = sizeof(type); \ ret = UC_ERR_OK; \ } while(0) diff --git a/qemu/x86_64.h b/qemu/x86_64.h index aa03182d..860707b1 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -5,6 +5,9 @@ #define UNICORN_ARCH_POSTFIX _x86_64 #endif #define unicorn_fill_tlb unicorn_fill_tlb_x86_64 +#define reg_read reg_read_x86_64 +#define reg_write reg_write_x86_64 +#define uc_init uc_init_x86_64 #define uc_add_inline_hook uc_add_inline_hook_x86_64 #define uc_del_inline_hook uc_del_inline_hook_x86_64 #define tb_invalidate_phys_range tb_invalidate_phys_range_x86_64 @@ -1879,7 +1882,4 @@ #define x86_cpu_xrstor_all_areas x86_cpu_xrstor_all_areas_x86_64 #define cpu_get_fp80 cpu_get_fp80_x86_64 #define cpu_set_fp80 cpu_set_fp80_x86_64 -#define x86_reg_reset x86_reg_reset_x86_64 -#define x86_reg_read x86_reg_read_x86_64 -#define x86_reg_write x86_reg_write_x86_64 #endif diff --git a/symbols.sh b/symbols.sh index cbf5f0db..1c4f31f2 100755 --- a/symbols.sh +++ b/symbols.sh @@ -5,6 +5,9 @@ SOURCE_DIR=$(dirname ${CMD_PATH}) COMMON_SYMBOLS=" unicorn_fill_tlb \ +reg_read \ +reg_write \ +uc_init \ uc_add_inline_hook \ uc_del_inline_hook \ tb_invalidate_phys_range \ @@ -1882,9 +1885,6 @@ x86_cpu_xsave_all_areas \ x86_cpu_xrstor_all_areas \ cpu_get_fp80 \ cpu_set_fp80 \ -x86_reg_reset \ -x86_reg_read \ -x86_reg_write \ " arm_SYMBOLS=" @@ -2580,9 +2580,6 @@ helper_frint64_s \ helper_frint32_d \ helper_frint64_d \ helper_check_hcr_el2_trap \ -arm_reg_reset \ -arm_reg_read \ -arm_reg_write \ mla_op \ mls_op \ sshl_op \ @@ -4280,9 +4277,6 @@ helper_frint64_s \ helper_frint32_d \ helper_frint64_d \ helper_check_hcr_el2_trap \ -arm64_reg_reset \ -arm64_reg_read \ -arm64_reg_write \ mla_op \ mls_op \ sshl_op \ @@ -4385,9 +4379,6 @@ gen_intermediate_code \ riscv_translate_init \ restore_state_to_opc \ cpu_riscv_init \ -riscv_reg_reset \ -riscv_reg_read \ -riscv_reg_write \ helper_fcvt_l_s \ helper_fcvt_lu_s \ helper_fcvt_s_l \ @@ -5511,9 +5502,6 @@ mips_tcg_init \ cpu_mips_realize_env \ cpu_state_reset \ restore_state_to_opc \ -mips_reg_reset \ -mips_reg_read \ -mips_reg_write \ ieee_rm \ mips_defs \ mips_defs_number \ @@ -5665,9 +5653,6 @@ helper_wrpstate \ helper_wrpil \ helper_done \ helper_retry \ -sparc_reg_reset \ -sparc_reg_read \ -sparc_reg_write \ " sparc64_SYMBOLS=${sparc_SYMBOLS} @@ -5828,17 +5813,11 @@ m68k_tcg_init \ register_m68k_insns \ gen_intermediate_code \ restore_state_to_opc \ -m68k_reg_reset \ -m68k_reg_read \ -m68k_reg_write \ " ppc_SYMBOLS=" ppc_cpu_unrealize \ ppc_cpu_instance_finalize \ -ppc_reg_reset \ -ppc_reg_read \ -ppc_reg_write \ ppc_cpu_do_interrupt \ ppc_cpu_do_system_reset \ ppc_cpu_do_fwnmi_machine_check \ diff --git a/uc.c b/uc.c index 0581c408..0c7a8f32 100644 --- a/uc.c +++ b/uc.c @@ -82,14 +82,14 @@ unsigned int uc_version(unsigned int *major, unsigned int *minor) UC_API_EXTRA; } -static int default_reg_read(struct uc_struct *uc, unsigned int *regs, - void *const *vals, size_t *sizes, int count) +static uc_err default_reg_read(void *env, int mode, unsigned int regid, + void *value, size_t *size) { return UC_ERR_HANDLE; } -static int default_reg_write(struct uc_struct *uc, unsigned int *regs, - const void *const *vals, size_t *sizes, int count) +static uc_err default_reg_write(void *env, int mode, unsigned int regid, + const void *value, size_t *size, int *setpc) { return UC_ERR_HANDLE; } @@ -203,7 +203,7 @@ bool uc_arch_supported(uc_arch arch) #define UC_INIT(uc) \ if (unlikely(!(uc)->init_done)) { \ - int __init_ret = uc_init(uc); \ + int __init_ret = uc_init_engine(uc); \ if (unlikely(__init_ret != UC_ERR_OK)) { \ return __init_ret; \ } \ @@ -223,7 +223,7 @@ static gint uc_exits_cmp(gconstpointer a, gconstpointer b, gpointer user_data) } } -static uc_err uc_init(uc_engine *uc) +static uc_err uc_init_engine(uc_engine *uc) { if (uc->init_done) { @@ -295,7 +295,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = m68k_uc_init; + uc->init_arch = uc_init_m68k; break; #endif #ifdef UNICORN_HAS_X86 @@ -305,7 +305,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = x86_uc_init; + uc->init_arch = uc_init_x86_64; break; #endif #ifdef UNICORN_HAS_ARM @@ -314,7 +314,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = arm_uc_init; + uc->init_arch = uc_init_arm; if (mode & UC_MODE_THUMB) { uc->thumb = 1; @@ -327,7 +327,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = arm64_uc_init; + uc->init_arch = uc_init_aarch64; break; #endif @@ -342,23 +342,23 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) if (mode & UC_MODE_BIG_ENDIAN) { #ifdef UNICORN_HAS_MIPS if (mode & UC_MODE_MIPS32) { - uc->init_arch = mips_uc_init; + uc->init_arch = uc_init_mips; } #endif #ifdef UNICORN_HAS_MIPS64 if (mode & UC_MODE_MIPS64) { - uc->init_arch = mips64_uc_init; + uc->init_arch = uc_init_mips64; } #endif } else { // little endian #ifdef UNICORN_HAS_MIPSEL if (mode & UC_MODE_MIPS32) { - uc->init_arch = mipsel_uc_init; + uc->init_arch = uc_init_mipsel; } #endif #ifdef UNICORN_HAS_MIPS64EL if (mode & UC_MODE_MIPS64) { - uc->init_arch = mips64el_uc_init; + uc->init_arch = uc_init_mips64el; } #endif } @@ -373,9 +373,9 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) return UC_ERR_MODE; } if (mode & UC_MODE_SPARC64) { - uc->init_arch = sparc64_uc_init; + uc->init_arch = uc_init_sparc64; } else { - uc->init_arch = sparc_uc_init; + uc->init_arch = uc_init_sparc; } break; #endif @@ -387,9 +387,9 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) return UC_ERR_MODE; } if (mode & UC_MODE_PPC64) { - uc->init_arch = ppc64_uc_init; + uc->init_arch = uc_init_ppc64; } else { - uc->init_arch = ppc_uc_init; + uc->init_arch = uc_init_ppc; } break; #endif @@ -401,9 +401,9 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) return UC_ERR_MODE; } if (mode & UC_MODE_RISCV32) { - uc->init_arch = riscv32_uc_init; + uc->init_arch = uc_init_riscv32; } else if (mode & UC_MODE_RISCV64) { - uc->init_arch = riscv64_uc_init; + uc->init_arch = uc_init_riscv64; } else { free(uc); return UC_ERR_MODE; @@ -416,7 +416,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = s390_uc_init; + uc->init_arch = uc_init_s390x; break; #endif #ifdef UNICORN_HAS_TRICORE @@ -425,7 +425,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) free(uc); return UC_ERR_MODE; } - uc->init_arch = tricore_uc_init; + uc->init_arch = uc_init_tricore; break; #endif } @@ -519,62 +519,158 @@ uc_err uc_close(uc_engine *uc) } UNICORN_EXPORT -uc_err uc_reg_read_batch(uc_engine *uc, int *ids, void **vals, int count) +uc_err uc_reg_read_batch(uc_engine *uc, int *regs, void **vals, int count) { UC_INIT(uc); - return uc->reg_read(uc, (unsigned int *)ids, vals, NULL, count); + reg_read_t reg_read = uc->reg_read; + void *env = uc->cpu->env_ptr; + int mode = uc->mode; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + void *value = vals[i]; + size_t size = (size_t)-1; + uc_err err = reg_read(env, mode, regid, value, &size); + if (err) { + return err; + } + } + + return UC_ERR_OK; } UNICORN_EXPORT -uc_err uc_reg_write_batch(uc_engine *uc, int *ids, void *const *vals, int count) +uc_err uc_reg_write_batch(uc_engine *uc, int *regs, void *const *vals, + int count) { UC_INIT(uc); - return uc->reg_write(uc, (unsigned int *)ids, (const void *const *)vals, - NULL, count); + reg_write_t reg_write = uc->reg_write; + void *env = uc->cpu->env_ptr; + int mode = uc->mode; + int setpc = 0; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + const void *value = vals[i]; + size_t size = (size_t)-1; + uc_err err = reg_write(env, mode, regid, value, &size, &setpc); + if (err) { + return err; + } + } + if (setpc) { + // force to quit execution and flush TB + uc->quit_request = true; + break_translation_loop(uc); + } + + return UC_ERR_OK; } UNICORN_EXPORT -uc_err uc_reg_read_batch2(uc_engine *uc, int *ids, void *const *vals, +uc_err uc_reg_read_batch2(uc_engine *uc, int *regs, void *const *vals, size_t *sizes, int count) { UC_INIT(uc); - return uc->reg_read(uc, (unsigned int *)ids, vals, sizes, count); + reg_read_t reg_read = uc->reg_read; + void *env = uc->cpu->env_ptr; + int mode = uc->mode; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + void *value = vals[i]; + uc_err err = reg_read(env, mode, regid, value, sizes + i); + if (err) { + return err; + } + } + + return UC_ERR_OK; } UNICORN_EXPORT -uc_err uc_reg_write_batch2(uc_engine *uc, int *ids, const void *const *vals, +uc_err uc_reg_write_batch2(uc_engine *uc, int *regs, const void *const *vals, size_t *sizes, int count) { UC_INIT(uc); - return uc->reg_write(uc, (unsigned int *)ids, vals, sizes, count); + reg_write_t reg_write = uc->reg_write; + void *env = uc->cpu->env_ptr; + int mode = uc->mode; + int setpc = 0; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + const void *value = vals[i]; + uc_err err = reg_write(env, mode, regid, value, sizes + i, &setpc); + if (err) { + return err; + } + } + if (setpc) { + // force to quit execution and flush TB + uc->quit_request = true; + break_translation_loop(uc); + } + + return UC_ERR_OK; } UNICORN_EXPORT uc_err uc_reg_read(uc_engine *uc, int regid, void *value) { UC_INIT(uc); - return uc->reg_read(uc, (unsigned int *)®id, &value, NULL, 1); + size_t size = (size_t)-1; + return uc->reg_read(uc->cpu->env_ptr, uc->mode, regid, value, &size); } UNICORN_EXPORT uc_err uc_reg_write(uc_engine *uc, int regid, const void *value) { UC_INIT(uc); - return uc->reg_write(uc, (unsigned int *)®id, &value, NULL, 1); + int setpc = 0; + size_t size = (size_t)-1; + uc_err err = + uc->reg_write(uc->cpu->env_ptr, uc->mode, regid, value, &size, &setpc); + if (err) { + return err; + } + if (setpc) { + // force to quit execution and flush TB + uc->quit_request = true; + break_translation_loop(uc); + } + + return UC_ERR_OK; } UNICORN_EXPORT uc_err uc_reg_read2(uc_engine *uc, int regid, void *value, size_t *size) { UC_INIT(uc); - return uc->reg_read(uc, (unsigned int *)®id, &value, size, 1); + return uc->reg_read(uc->cpu->env_ptr, uc->mode, regid, value, size); } UNICORN_EXPORT uc_err uc_reg_write2(uc_engine *uc, int regid, const void *value, size_t *size) { UC_INIT(uc); - return uc->reg_write(uc, (unsigned int *)®id, &value, size, 1); + int setpc = 0; + uc_err err = + uc->reg_write(uc->cpu->env_ptr, uc->mode, regid, value, size, &setpc); + if (err) { + return err; + } + if (setpc) { + // force to quit execution and flush TB + uc->quit_request = true; + break_translation_loop(uc); + } + + return UC_ERR_OK; } // check if a memory area is mapped @@ -1893,79 +1989,36 @@ uc_err uc_context_save(uc_engine *uc, uc_context *context) } } -UNICORN_EXPORT -uc_err uc_context_reg_write(uc_context *ctx, int regid, const void *value) -{ - return uc_context_reg_write_batch2(ctx, ®id, &value, NULL, 1); -} - -UNICORN_EXPORT -uc_err uc_context_reg_read(uc_context *ctx, int regid, void *value) -{ - return uc_context_reg_read_batch2(ctx, ®id, &value, NULL, 1); -} - -UNICORN_EXPORT -uc_err uc_context_reg_write2(uc_context *ctx, int regid, const void *value, - size_t *size) -{ - return uc_context_reg_write_batch2(ctx, ®id, &value, size, 1); -} - -UNICORN_EXPORT -uc_err uc_context_reg_read2(uc_context *ctx, int regid, void *value, - size_t *size) -{ - return uc_context_reg_read_batch2(ctx, ®id, &value, size, 1); -} - -UNICORN_EXPORT -uc_err uc_context_reg_write_batch(uc_context *ctx, int *ids, void *const *vals, - int count) -{ - return uc_context_reg_write_batch2(ctx, ids, (const void *const *)vals, - NULL, count); -} - -UNICORN_EXPORT -uc_err uc_context_reg_read_batch(uc_context *ctx, int *ids, void **vals, - int count) -{ - return uc_context_reg_read_batch2(ctx, ids, vals, NULL, count); -} - // Keep in mind that we don't a uc_engine when r/w the registers of a context. -static void find_context_reg_rw_function(uc_arch arch, uc_mode mode, - context_reg_rw_t *rw) +static context_reg_rw_t find_context_reg_rw(uc_arch arch, uc_mode mode) { // We believe that the arch/mode pair is correct. + context_reg_rw_t rw = {default_reg_read, default_reg_write}; switch (arch) { default: - rw->context_reg_read = NULL; - rw->context_reg_write = NULL; break; #ifdef UNICORN_HAS_M68K case UC_ARCH_M68K: - rw->context_reg_read = m68k_context_reg_read; - rw->context_reg_write = m68k_context_reg_write; + rw.read = reg_read_m68k; + rw.write = reg_write_m68k; break; #endif #ifdef UNICORN_HAS_X86 case UC_ARCH_X86: - rw->context_reg_read = x86_context_reg_read; - rw->context_reg_write = x86_context_reg_write; + rw.read = reg_read_x86_64; + rw.write = reg_write_x86_64; break; #endif #ifdef UNICORN_HAS_ARM case UC_ARCH_ARM: - rw->context_reg_read = arm_context_reg_read; - rw->context_reg_write = arm_context_reg_write; + rw.read = reg_read_arm; + rw.write = reg_write_arm; break; #endif #ifdef UNICORN_HAS_ARM64 case UC_ARCH_ARM64: - rw->context_reg_read = arm64_context_reg_read; - rw->context_reg_write = arm64_context_reg_write; + rw.read = reg_read_aarch64; + rw.write = reg_write_aarch64; break; #endif @@ -1975,27 +2028,27 @@ static void find_context_reg_rw_function(uc_arch arch, uc_mode mode, if (mode & UC_MODE_BIG_ENDIAN) { #ifdef UNICORN_HAS_MIPS if (mode & UC_MODE_MIPS32) { - rw->context_reg_read = mips_context_reg_read; - rw->context_reg_write = mips_context_reg_write; + rw.read = reg_read_mips; + rw.write = reg_write_mips; } #endif #ifdef UNICORN_HAS_MIPS64 if (mode & UC_MODE_MIPS64) { - rw->context_reg_read = mips64_context_reg_read; - rw->context_reg_write = mips64_context_reg_write; + rw.read = reg_read_mips64; + rw.write = reg_write_mips64; } #endif } else { // little endian #ifdef UNICORN_HAS_MIPSEL if (mode & UC_MODE_MIPS32) { - rw->context_reg_read = mipsel_context_reg_read; - rw->context_reg_write = mipsel_context_reg_write; + rw.read = reg_read_mipsel; + rw.write = reg_write_mipsel; } #endif #ifdef UNICORN_HAS_MIPS64EL if (mode & UC_MODE_MIPS64) { - rw->context_reg_read = mips64el_context_reg_read; - rw->context_reg_write = mips64el_context_reg_write; + rw.read = reg_read_mips64el; + rw.write = reg_write_mips64el; } #endif } @@ -2005,82 +2058,174 @@ static void find_context_reg_rw_function(uc_arch arch, uc_mode mode, #ifdef UNICORN_HAS_SPARC case UC_ARCH_SPARC: if (mode & UC_MODE_SPARC64) { - rw->context_reg_read = sparc64_context_reg_read; - rw->context_reg_write = sparc64_context_reg_write; + rw.read = reg_read_sparc64; + rw.write = reg_write_sparc64; } else { - rw->context_reg_read = sparc_context_reg_read; - rw->context_reg_write = sparc_context_reg_write; + rw.read = reg_read_sparc; + rw.write = reg_write_sparc; } break; #endif #ifdef UNICORN_HAS_PPC case UC_ARCH_PPC: if (mode & UC_MODE_PPC64) { - rw->context_reg_read = ppc64_context_reg_read; - rw->context_reg_write = ppc64_context_reg_write; + rw.read = reg_read_ppc64; + rw.write = reg_write_ppc64; } else { - rw->context_reg_read = ppc_context_reg_read; - rw->context_reg_write = ppc_context_reg_write; + rw.read = reg_read_ppc; + rw.write = reg_write_ppc; } break; #endif #ifdef UNICORN_HAS_RISCV case UC_ARCH_RISCV: if (mode & UC_MODE_RISCV32) { - rw->context_reg_read = riscv32_context_reg_read; - rw->context_reg_write = riscv32_context_reg_write; + rw.read = reg_read_riscv32; + rw.write = reg_write_riscv32; } else if (mode & UC_MODE_RISCV64) { - rw->context_reg_read = riscv64_context_reg_read; - rw->context_reg_write = riscv64_context_reg_write; + rw.read = reg_read_riscv64; + rw.write = reg_write_riscv64; } break; #endif #ifdef UNICORN_HAS_S390X case UC_ARCH_S390X: - rw->context_reg_read = s390_context_reg_read; - rw->context_reg_write = s390_context_reg_write; + rw.read = reg_read_s390x; + rw.write = reg_write_s390x; break; #endif #ifdef UNICORN_HAS_TRICORE case UC_ARCH_TRICORE: - rw->context_reg_read = tricore_context_reg_read; - rw->context_reg_write = tricore_context_reg_write; + rw.read = reg_read_tricore; + rw.write = reg_write_tricore; break; #endif } - return; + return rw; } UNICORN_EXPORT -uc_err uc_context_reg_write_batch2(uc_context *ctx, int *ids, +uc_err uc_context_reg_write(uc_context *ctx, int regid, const void *value) +{ + int setpc = 0; + size_t size = (size_t)-1; + return find_context_reg_rw(ctx->arch, ctx->mode) + .write(ctx->data, ctx->mode, regid, value, &size, &setpc); +} + +UNICORN_EXPORT +uc_err uc_context_reg_read(uc_context *ctx, int regid, void *value) +{ + size_t size = (size_t)-1; + return find_context_reg_rw(ctx->arch, ctx->mode) + .read(ctx->data, ctx->mode, regid, value, &size); +} + +UNICORN_EXPORT +uc_err uc_context_reg_write2(uc_context *ctx, int regid, const void *value, + size_t *size) +{ + int setpc = 0; + return find_context_reg_rw(ctx->arch, ctx->mode) + .write(ctx->data, ctx->mode, regid, value, size, &setpc); +} + +UNICORN_EXPORT +uc_err uc_context_reg_read2(uc_context *ctx, int regid, void *value, + size_t *size) +{ + return find_context_reg_rw(ctx->arch, ctx->mode) + .read(ctx->data, ctx->mode, regid, value, size); +} + +UNICORN_EXPORT +uc_err uc_context_reg_write_batch(uc_context *ctx, int *regs, void *const *vals, + int count) +{ + reg_write_t reg_write = find_context_reg_rw(ctx->arch, ctx->mode).write; + void *env = ctx->data; + int mode = ctx->mode; + int setpc = 0; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + const void *value = vals[i]; + size_t size = (size_t)-1; + uc_err err = reg_write(env, mode, regid, value, &size, &setpc); + if (err) { + return err; + } + } + + return UC_ERR_OK; +} + +UNICORN_EXPORT +uc_err uc_context_reg_read_batch(uc_context *ctx, int *regs, void **vals, + int count) +{ + reg_read_t reg_read = find_context_reg_rw(ctx->arch, ctx->mode).read; + void *env = ctx->data; + int mode = ctx->mode; + int i; + + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + void *value = vals[i]; + size_t size = (size_t)-1; + uc_err err = reg_read(env, mode, regid, value, &size); + if (err) { + return err; + } + } + + return UC_ERR_OK; +} + +UNICORN_EXPORT +uc_err uc_context_reg_write_batch2(uc_context *ctx, int *regs, const void *const *vals, size_t *sizes, int count) { - context_reg_rw_t rw; + reg_write_t reg_write = find_context_reg_rw(ctx->arch, ctx->mode).write; + void *env = ctx->data; + int mode = ctx->mode; + int setpc = 0; + int i; - find_context_reg_rw_function(ctx->arch, ctx->mode, &rw); - if (rw.context_reg_write) { - return rw.context_reg_write(ctx, (unsigned int *)ids, vals, sizes, - count); - } else { - return UC_ERR_HANDLE; + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + const void *value = vals[i]; + uc_err err = reg_write(env, mode, regid, value, sizes + i, &setpc); + if (err) { + return err; + } } + + return UC_ERR_OK; } UNICORN_EXPORT -uc_err uc_context_reg_read_batch2(uc_context *ctx, int *ids, void *const *vals, +uc_err uc_context_reg_read_batch2(uc_context *ctx, int *regs, void *const *vals, size_t *sizes, int count) { - context_reg_rw_t rw; + reg_read_t reg_read = find_context_reg_rw(ctx->arch, ctx->mode).read; + void *env = ctx->data; + int mode = ctx->mode; + int i; - find_context_reg_rw_function(ctx->arch, ctx->mode, &rw); - if (rw.context_reg_read) { - return rw.context_reg_read(ctx, (unsigned int *)ids, vals, sizes, - count); - } else { - return UC_ERR_HANDLE; + for (i = 0; i < count; i++) { + unsigned int regid = regs[i]; + void *value = vals[i]; + uc_err err = reg_read(env, mode, regid, value, sizes + i); + if (err) { + return err; + } } + + return UC_ERR_OK; } UNICORN_EXPORT @@ -2099,7 +2244,6 @@ uc_err uc_context_restore(uc_engine *uc, uc_context *context) UNICORN_EXPORT uc_err uc_context_free(uc_context *context) { - return uc_free(context); }