diff --git a/include/uc_priv.h b/include/uc_priv.h index a65664a4..5fbdda07 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -63,15 +63,16 @@ 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 **vals, - int count); +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, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); typedef int (*context_reg_read_t)(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); typedef int (*context_reg_write_t)(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + 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; diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index e7d9d4d1..dbe8d027 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -779,10 +779,9 @@ const char *uc_strerror(uc_err code); @uc: handle returned by uc_open() @regid: register ID that is to be modified. - @value: pointer to the value that will set to register @regid + @value: pointer to the value that will be written to register @regid - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is invalid */ UNICORN_EXPORT uc_err uc_reg_write(uc_engine *uc, int regid, const void *value); @@ -794,22 +793,49 @@ uc_err uc_reg_write(uc_engine *uc, int regid, const void *value); @regid: register ID that is to be retrieved. @value: pointer to a variable storing the register value. - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is invalid */ UNICORN_EXPORT uc_err uc_reg_read(uc_engine *uc, int regid, void *value); +/* + Write to register. + + @uc: handle returned by uc_open() + @regid: register ID that is to be modified. + @value: pointer to the value that will be written to register @regid + @size: size of value being written; on return, size of value written + + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is + invalid; UC_ERR_NOMEM if value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_reg_write2(uc_engine *uc, int regid, const void *value, size_t *size); + +/* + Read register value. + + @uc: handle returned by uc_open() + @regid: register ID that is to be retrieved. + @value: pointer to a variable storing the register value. + @size: size of value buffer; on return, size of value read + + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is + invalid; UC_ERR_NOMEM if value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_reg_read2(uc_engine *uc, int regid, void *value, size_t *size); + /* Write multiple register values. @uc: handle returned by uc_open() - @rges: array of register IDs to store - @value: pointer to array of register values + @regs: array of register IDs to store + @vals: array of pointers to register values @count: length of both *regs and *vals - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid */ UNICORN_EXPORT uc_err uc_reg_write_batch(uc_engine *uc, int *regs, void *const *vals, @@ -819,16 +845,49 @@ uc_err uc_reg_write_batch(uc_engine *uc, int *regs, void *const *vals, Read multiple register values. @uc: handle returned by uc_open() - @rges: array of register IDs to retrieve - @value: pointer to array of values to hold registers + @regs: array of register IDs to retrieve + @vals: array of pointers to register values @count: length of both *regs and *vals - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid */ UNICORN_EXPORT uc_err uc_reg_read_batch(uc_engine *uc, int *regs, void **vals, int count); +/* + Write multiple register values. + + @uc: handle returned by uc_open() + @regs: array of register IDs to store + @value: array of pointers to register values + @sizes: array of sizes of each value; on return, sizes of each stored register + @count: length of *regs, *vals and *sizes + + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid; UC_ERR_NOMEM if some value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_reg_write_batch2(uc_engine *uc, int *regs, const void *const *vals, + size_t *sizes, int count); + +/* + Read multiple register values. + + @uc: handle returned by uc_open() + @regs: array of register IDs to retrieve + @value: pointer to array of values to hold registers + @sizes: array of sizes of each value; on return, sizes of each retrieved + register + @count: length of *regs, *vals and *sizes + + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid; UC_ERR_NOMEM if some value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_reg_read_batch2(uc_engine *uc, int *regs, void *const *vals, + size_t *sizes, int count); + /* Write to a range of bytes in memory. @@ -1131,10 +1190,9 @@ uc_err uc_context_save(uc_engine *uc, uc_context *context); @ctx: handle returned by uc_context_alloc() @regid: register ID that is to be modified. - @value: pointer to the value that will set to register @regid + @value: pointer to the value that will be written to register @regid - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is invalid */ UNICORN_EXPORT uc_err uc_context_reg_write(uc_context *ctx, int regid, const void *value); @@ -1146,12 +1204,41 @@ uc_err uc_context_reg_write(uc_context *ctx, int regid, const void *value); @regid: register ID that is to be retrieved. @value: pointer to a variable storing the register value. - @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum - for detailed error). + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is invalid */ UNICORN_EXPORT uc_err uc_context_reg_read(uc_context *ctx, int regid, void *value); +/* + Write value to a register of a context. + + @ctx: handle returned by uc_context_alloc() + @regid: register ID that is to be modified. + @value: pointer to the value that will be written to register @regid + @size: size of value being written; on return, size of value written + + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is + invalid; UC_ERR_NOMEM if value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_context_reg_write2(uc_context *ctx, int regid, const void *value, + size_t *size); + +/* + Read register value from a context. + + @ctx: handle returned by uc_context_alloc() + @regid: register ID that is to be retrieved. + @value: pointer to a variable storing the register value. + @size: size of value buffer; on return, size of value read + + @return UC_ERR_OK on success; UC_ERR_ARG if register number or value is + invalid; UC_ERR_NOMEM if value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_context_reg_read2(uc_context *ctx, int regid, void *value, + size_t *size); + /* Write multiple register values to registers of a context. @@ -1182,6 +1269,40 @@ UNICORN_EXPORT uc_err uc_context_reg_read_batch(uc_context *ctx, int *regs, void **vals, int count); +/* + Write multiple register values to registers of a context. + + @ctx: handle returned by uc_context_alloc() + @regs: array of register IDs to store + @value: array of pointers to register values + @sizes: array of sizes of each value; on return, sizes of each stored register + @count: length of *regs, *vals and *sizes + + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid; UC_ERR_NOMEM if some value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_context_reg_write_batch2(uc_context *ctx, int *regs, + const void *const *vals, size_t *sizes, + int count); + +/* + Read multiple register values from a context. + + @ctx: handle returned by uc_context_alloc() + @regs: array of register IDs to retrieve + @value: pointer to array of values to hold registers + @sizes: array of sizes of each value; on return, sizes of each retrieved + register + @count: length of *regs, *vals and *sizes + + @return UC_ERR_OK on success; UC_ERR_ARG if some register number or value is + invalid; UC_ERR_NOMEM if some value is not large enough. +*/ +UNICORN_EXPORT +uc_err uc_context_reg_read_batch2(uc_context *ctx, int *regs, void *const *vals, + size_t *sizes, int count); + /* Restore the current CPU context from a saved copy. This API should be used to roll the CPU context back to a previous diff --git a/qemu/target/arm/unicorn.h b/qemu/target/arm/unicorn.h index df0b20a0..18612489 100644 --- a/qemu/target/arm/unicorn.h +++ b/qemu/target/arm/unicorn.h @@ -5,23 +5,23 @@ #define UC_QEMU_TARGET_ARM_H // functions to read & write registers -int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); -int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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); int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + 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); diff --git a/qemu/target/arm/unicorn_aarch64.c b/qemu/target/arm/unicorn_aarch64.c index e3bc63a3..f8d4446d 100644 --- a/qemu/target/arm/unicorn_aarch64.c +++ b/qemu/target/arm/unicorn_aarch64.c @@ -138,97 +138,127 @@ 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) +static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, + size_t *size) { - uc_err ret = UC_ERR_OK; + uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) { regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0; } if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) { - *(int64_t *)value = env->xregs[regid - UC_ARM64_REG_X0]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->xregs[regid - UC_ARM64_REG_X0]; } else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) { - *(int32_t *)value = READ_DWORD(env->xregs[regid - UC_ARM64_REG_W0]); + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = READ_DWORD(env->xregs[regid - UC_ARM64_REG_W0]); } else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) { // FIXME + CHECK_REG_TYPE(float64[2]); float64 *dst = (float64 *)value; uint32_t reg_index = regid - UC_ARM64_REG_Q0; dst[0] = env->vfp.zregs[reg_index].d[0]; dst[1] = env->vfp.zregs[reg_index].d[1]; } else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) { + CHECK_REG_TYPE(float64); *(float64 *)value = env->vfp.zregs[regid - UC_ARM64_REG_D0].d[0]; } else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) { + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->vfp.zregs[regid - UC_ARM64_REG_S0].d[0]); } else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) { + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->vfp.zregs[regid - UC_ARM64_REG_H0].d[0]); } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) { + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->vfp.zregs[regid - UC_ARM64_REG_B0].d[0]); } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->elr_el[regid - UC_ARM64_REG_ELR_EL0]; } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->sp_el[regid - UC_ARM64_REG_SP_EL0]; } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0]; } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.far_el[regid - UC_ARM64_REG_FAR_EL0]; } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0]; } else { switch (regid) { default: break; case UC_ARM64_REG_CPACR_EL1: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->cp15.cpacr_el1; break; case UC_ARM64_REG_TPIDR_EL0: - *(int64_t *)value = env->cp15.tpidr_el[0]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->cp15.tpidr_el[0]; break; case UC_ARM64_REG_TPIDRRO_EL0: - *(int64_t *)value = env->cp15.tpidrro_el[0]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->cp15.tpidrro_el[0]; break; case UC_ARM64_REG_TPIDR_EL1: - *(int64_t *)value = env->cp15.tpidr_el[1]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->cp15.tpidr_el[1]; break; case UC_ARM64_REG_X29: - *(int64_t *)value = env->xregs[29]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->xregs[29]; break; case UC_ARM64_REG_X30: - *(int64_t *)value = env->xregs[30]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->xregs[30]; break; case UC_ARM64_REG_PC: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->pc; break; case UC_ARM64_REG_SP: - *(int64_t *)value = env->xregs[31]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->xregs[31]; break; case UC_ARM64_REG_NZCV: - *(int32_t *)value = cpsr_read(env) & CPSR_NZCV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = cpsr_read(env) & CPSR_NZCV; break; case UC_ARM64_REG_PSTATE: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = pstate_read(env); break; case UC_ARM64_REG_TTBR0_EL1: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.ttbr0_el[1]; break; case UC_ARM64_REG_TTBR1_EL1: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.ttbr1_el[1]; break; case UC_ARM64_REG_PAR_EL1: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.par_el[1]; break; case UC_ARM64_REG_MAIR_EL1: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->cp15.mair_el[1]; break; case UC_ARM64_REG_CP_REG: + CHECK_REG_TYPE(uc_arm64_cp_reg); ret = read_cp_reg(env, (uc_arm64_cp_reg *)value); break; case UC_ARM64_REG_FPCR: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = vfp_get_fpcr(env); break; case UC_ARM64_REG_FPSR: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = vfp_get_fpsr(env); break; } @@ -237,98 +267,128 @@ 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) +static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, + size_t *size) { - uc_err ret = UC_ERR_OK; + uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) { regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0; } if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) { + CHECK_REG_TYPE(uint64_t); env->xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value; } else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) { + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->xregs[regid - UC_ARM64_REG_W0], *(uint32_t *)value); } else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) { + CHECK_REG_TYPE(float64[2]); float64 *src = (float64 *)value; uint32_t reg_index = regid - UC_ARM64_REG_Q0; env->vfp.zregs[reg_index].d[0] = src[0]; env->vfp.zregs[reg_index].d[1] = src[1]; } else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) { + CHECK_REG_TYPE(float64); env->vfp.zregs[regid - UC_ARM64_REG_D0].d[0] = *(float64 *)value; } else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) { + CHECK_REG_TYPE(int32_t); WRITE_DWORD(env->vfp.zregs[regid - UC_ARM64_REG_S0].d[0], *(int32_t *)value); } else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) { + CHECK_REG_TYPE(int16_t); WRITE_WORD(env->vfp.zregs[regid - UC_ARM64_REG_H0].d[0], *(int16_t *)value); } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) { + CHECK_REG_TYPE(int8_t); WRITE_BYTE_L(env->vfp.zregs[regid - UC_ARM64_REG_B0].d[0], *(int8_t *)value); } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) { + CHECK_REG_TYPE(uint64_t); env->elr_el[regid - UC_ARM64_REG_ELR_EL0] = *(uint64_t *)value; } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) { + CHECK_REG_TYPE(uint64_t); env->sp_el[regid - UC_ARM64_REG_SP_EL0] = *(uint64_t *)value; } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) { + CHECK_REG_TYPE(uint64_t); env->cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0] = *(uint64_t *)value; } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) { + CHECK_REG_TYPE(uint64_t); env->cp15.far_el[regid - UC_ARM64_REG_FAR_EL0] = *(uint64_t *)value; } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) { + CHECK_REG_TYPE(uint64_t); env->cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0] = *(uint64_t *)value; } else { switch (regid) { default: break; case UC_ARM64_REG_CPACR_EL1: + CHECK_REG_TYPE(uint32_t); env->cp15.cpacr_el1 = *(uint32_t *)value; break; case UC_ARM64_REG_TPIDR_EL0: + CHECK_REG_TYPE(uint64_t); env->cp15.tpidr_el[0] = *(uint64_t *)value; break; case UC_ARM64_REG_TPIDRRO_EL0: + CHECK_REG_TYPE(uint64_t); env->cp15.tpidrro_el[0] = *(uint64_t *)value; break; case UC_ARM64_REG_TPIDR_EL1: + CHECK_REG_TYPE(uint64_t); env->cp15.tpidr_el[1] = *(uint64_t *)value; break; case UC_ARM64_REG_X29: + CHECK_REG_TYPE(uint64_t); env->xregs[29] = *(uint64_t *)value; break; case UC_ARM64_REG_X30: + CHECK_REG_TYPE(uint64_t); env->xregs[30] = *(uint64_t *)value; break; case UC_ARM64_REG_PC: + CHECK_REG_TYPE(uint64_t); env->pc = *(uint64_t *)value; break; case UC_ARM64_REG_SP: + CHECK_REG_TYPE(uint64_t); env->xregs[31] = *(uint64_t *)value; break; case UC_ARM64_REG_NZCV: + CHECK_REG_TYPE(uint32_t); cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteRaw); break; case UC_ARM64_REG_PSTATE: + CHECK_REG_TYPE(uint32_t); pstate_write(env, *(uint32_t *)value); break; case UC_ARM64_REG_TTBR0_EL1: + CHECK_REG_TYPE(uint64_t); env->cp15.ttbr0_el[1] = *(uint64_t *)value; break; case UC_ARM64_REG_TTBR1_EL1: + CHECK_REG_TYPE(uint64_t); env->cp15.ttbr1_el[1] = *(uint64_t *)value; break; case UC_ARM64_REG_PAR_EL1: + CHECK_REG_TYPE(uint64_t); env->cp15.par_el[1] = *(uint64_t *)value; break; case UC_ARM64_REG_MAIR_EL1: + CHECK_REG_TYPE(uint64_t); env->cp15.mair_el[1] = *(uint64_t *)value; break; case UC_ARM64_REG_CP_REG: + CHECK_REG_TYPE(uc_arm64_cp_reg); ret = write_cp_reg(env, (uc_arm64_cp_reg *)value); arm_rebuild_hflags(env); break; case UC_ARM64_REG_FPCR: + CHECK_REG_TYPE(uint32_t); vfp_set_fpcr(env, *(uint32_t *)value); break; case UC_ARM64_REG_FPSR: + CHECK_REG_TYPE(uint32_t); vfp_set_fpsr(env, *(uint32_t *)value); break; } @@ -337,8 +397,8 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value) return ret; } -int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; @@ -347,7 +407,7 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - err = reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } @@ -356,8 +416,8 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, return UC_ERR_OK; } -int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; @@ -366,7 +426,7 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - err = reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } @@ -383,10 +443,10 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, DEFAULT_VISIBILITY #ifdef TARGET_WORDS_BIGENDIAN int arm64eb_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #else int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #endif { CPUARMState *env = (CPUARMState *)ctx->data; @@ -396,22 +456,22 @@ int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - err = reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_WORDS_BIGENDIAN int arm64eb_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #else int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #endif { CPUARMState *env = (CPUARMState *)ctx->data; @@ -421,13 +481,13 @@ int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - err = reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } } - return 0; + return UC_ERR_OK; } static int arm64_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/arm/unicorn_arm.c b/qemu/target/arm/unicorn_arm.c index e706b12b..3fc9704f 100644 --- a/qemu/target/arm/unicorn_arm.c +++ b/qemu/target/arm/unicorn_arm.c @@ -206,20 +206,25 @@ 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) +static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value, + size_t *size) { - uc_err ret = UC_ERR_OK; + uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM_REG_R0 && regid <= UC_ARM_REG_R12) { + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->regs[regid - UC_ARM_REG_R0]; } else if (regid >= UC_ARM_REG_Q0 && regid <= UC_ARM_REG_Q15) { + CHECK_REG_TYPE(uint64_t[2]); uint32_t reg_index = regid - UC_ARM_REG_Q0; *(uint64_t *)value = env->vfp.zregs[reg_index].d[0]; *(((uint64_t *)value) + 1) = env->vfp.zregs[reg_index].d[1]; } else if (regid >= UC_ARM_REG_D0 && regid <= UC_ARM_REG_D31) { + CHECK_REG_TYPE(uint64_t); uint32_t reg_index = regid - UC_ARM_REG_D0; *(uint64_t *)value = env->vfp.zregs[reg_index / 2].d[reg_index & 1]; } else if (regid >= UC_ARM_REG_S0 && regid <= UC_ARM_REG_S31) { + CHECK_REG_TYPE(uint32_t); uint32_t reg_index = regid - UC_ARM_REG_S0; uint64_t reg_value = env->vfp.zregs[reg_index / 4].d[reg_index % 4 / 2]; @@ -232,88 +237,115 @@ static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value) switch (regid) { case UC_ARM_REG_APSR: if (arm_feature(env, ARM_FEATURE_M)) { + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 0); } else { + CHECK_REG_TYPE(int32_t); *(int32_t *)value = cpsr_read(env) & (CPSR_NZCV | CPSR_Q | CPSR_GE); } break; case UC_ARM_REG_APSR_NZCV: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = cpsr_read(env) & CPSR_NZCV; break; case UC_ARM_REG_CPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = cpsr_read(env); break; case UC_ARM_REG_SPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->spsr; break; // case UC_ARM_REG_SP: case UC_ARM_REG_R13: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[13]; break; // case UC_ARM_REG_LR: case UC_ARM_REG_R14: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[14]; break; // case UC_ARM_REG_PC: case UC_ARM_REG_R15: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[15]; break; case UC_ARM_REG_C1_C0_2: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->cp15.cpacr_el1; break; case UC_ARM_REG_C13_C0_3: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->cp15.tpidrro_el[0]; break; case UC_ARM_REG_FPEXC: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->vfp.xregs[ARM_VFP_FPEXC]; break; case UC_ARM_REG_FPSCR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = vfp_get_fpscr(env); break; case UC_ARM_REG_FPSID: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->vfp.xregs[ARM_VFP_FPSID]; break; case UC_ARM_REG_IPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 5); break; case UC_ARM_REG_MSP: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 8); break; case UC_ARM_REG_PSP: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 9); break; case UC_ARM_REG_IAPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 1); break; case UC_ARM_REG_EAPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 2); break; case UC_ARM_REG_XPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 3); break; case UC_ARM_REG_EPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 6); break; case UC_ARM_REG_IEPSR: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = v7m_mrs_xpsr(env, 7); break; case UC_ARM_REG_PRIMASK: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 16); break; case UC_ARM_REG_BASEPRI: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 17); break; case UC_ARM_REG_BASEPRI_MAX: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 18); break; case UC_ARM_REG_FAULTMASK: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 19); break; case UC_ARM_REG_CONTROL: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = helper_v7m_mrs(env, 20); break; case UC_ARM_REG_CP_REG: + CHECK_REG_TYPE(uc_arm_cp_reg); ret = read_cp_reg(env, (uc_arm_cp_reg *)value); break; } @@ -322,20 +354,25 @@ 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) +static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value, + size_t *size) { - uc_err ret = UC_ERR_OK; + uc_err ret = UC_ERR_ARG; if (regid >= UC_ARM_REG_R0 && regid <= UC_ARM_REG_R12) { + CHECK_REG_TYPE(uint32_t); env->regs[regid - UC_ARM_REG_R0] = *(uint32_t *)value; } else if (regid >= UC_ARM_REG_Q0 && regid <= UC_ARM_REG_Q15) { + CHECK_REG_TYPE(uint64_t[2]); uint32_t reg_index = regid - UC_ARM_REG_Q0; env->vfp.zregs[reg_index].d[0] = *(uint64_t *)value; env->vfp.zregs[reg_index].d[1] = *(((uint64_t *)value) + 1); } else if (regid >= UC_ARM_REG_D0 && regid <= UC_ARM_REG_D31) { + CHECK_REG_TYPE(uint64_t); uint32_t reg_index = regid - UC_ARM_REG_D0; env->vfp.zregs[reg_index / 2].d[reg_index & 1] = *(uint64_t *)value; } else if (regid >= UC_ARM_REG_S0 && regid <= UC_ARM_REG_S31) { + CHECK_REG_TYPE(uint32_t); uint32_t reg_index = regid - UC_ARM_REG_S0; uint64_t *p_reg_value = &env->vfp.zregs[reg_index / 4].d[reg_index % 4 / 2]; @@ -350,6 +387,7 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value) } else { switch (regid) { case UC_ARM_REG_APSR: + CHECK_REG_TYPE(uint32_t); if (!arm_feature(env, ARM_FEATURE_M)) { cpsr_write(env, *(uint32_t *)value, (CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn); @@ -360,26 +398,32 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value) } break; case UC_ARM_REG_APSR_NZCV: + CHECK_REG_TYPE(uint32_t); cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn); arm_rebuild_hflags(env); break; case UC_ARM_REG_CPSR: + CHECK_REG_TYPE(uint32_t); cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn); arm_rebuild_hflags(env); break; case UC_ARM_REG_SPSR: + CHECK_REG_TYPE(uint32_t); env->spsr = *(uint32_t *)value; break; // case UC_ARM_REG_SP: case UC_ARM_REG_R13: + CHECK_REG_TYPE(uint32_t); env->regs[13] = *(uint32_t *)value; break; // case UC_ARM_REG_LR: case UC_ARM_REG_R14: + CHECK_REG_TYPE(uint32_t); env->regs[14] = *(uint32_t *)value; break; // case UC_ARM_REG_PC: case UC_ARM_REG_R15: + CHECK_REG_TYPE(uint32_t); env->pc = (*(uint32_t *)value & ~1); env->thumb = (*(uint32_t *)value & 1); env->uc->thumb = (*(uint32_t *)value & 1); @@ -390,87 +434,114 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value) // break; case UC_ARM_REG_C13_C0_3: + CHECK_REG_TYPE(int32_t); env->cp15.tpidrro_el[0] = *(int32_t *)value; break; case UC_ARM_REG_FPEXC: + CHECK_REG_TYPE(int32_t); env->vfp.xregs[ARM_VFP_FPEXC] = *(int32_t *)value; break; case UC_ARM_REG_FPSCR: + CHECK_REG_TYPE(int32_t); vfp_set_fpscr(env, *(int32_t *)value); break; case UC_ARM_REG_FPSID: + CHECK_REG_TYPE(int32_t); env->vfp.xregs[ARM_VFP_FPSID] = *(int32_t *)value; break; case UC_ARM_REG_IPSR: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 5, *(uint32_t *)value); break; case UC_ARM_REG_MSP: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 8, *(uint32_t *)value); break; case UC_ARM_REG_PSP: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 9, *(uint32_t *)value); break; case UC_ARM_REG_CONTROL: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 20, *(uint32_t *)value); break; case UC_ARM_REG_EPSR: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 6, *(uint32_t *)value); break; case UC_ARM_REG_IEPSR: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 7, *(uint32_t *)value); break; case UC_ARM_REG_PRIMASK: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 16, *(uint32_t *)value); break; case UC_ARM_REG_BASEPRI: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 17, *(uint32_t *)value); break; case UC_ARM_REG_BASEPRI_MAX: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 18, *(uint32_t *)value); break; case UC_ARM_REG_FAULTMASK: + CHECK_REG_TYPE(uint32_t); helper_v7m_msr(env, 19, *(uint32_t *)value); break; case UC_ARM_REG_APSR_NZCVQ: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value); break; case UC_ARM_REG_APSR_G: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b0100, 0, *(uint32_t *)value); break; case UC_ARM_REG_APSR_NZCVQG: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1100, 0, *(uint32_t *)value); break; case UC_ARM_REG_IAPSR: case UC_ARM_REG_IAPSR_NZCVQ: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 1, *(uint32_t *)value); break; case UC_ARM_REG_IAPSR_G: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b0100, 1, *(uint32_t *)value); break; case UC_ARM_REG_IAPSR_NZCVQG: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1100, 1, *(uint32_t *)value); break; case UC_ARM_REG_EAPSR: case UC_ARM_REG_EAPSR_NZCVQ: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 2, *(uint32_t *)value); break; case UC_ARM_REG_EAPSR_G: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b0100, 2, *(uint32_t *)value); break; case UC_ARM_REG_EAPSR_NZCVQG: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1100, 2, *(uint32_t *)value); break; case UC_ARM_REG_XPSR: case UC_ARM_REG_XPSR_NZCVQ: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1000, 3, *(uint32_t *)value); break; case UC_ARM_REG_XPSR_G: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b0100, 3, *(uint32_t *)value); break; case UC_ARM_REG_XPSR_NZCVQG: + CHECK_REG_TYPE(uint32_t); v7m_msr_xpsr(env, 0b1100, 3, *(uint32_t *)value); break; case UC_ARM_REG_CP_REG: + CHECK_REG_TYPE(uc_arm_cp_reg); ret = write_cp_reg(env, (uc_arm_cp_reg *)value); break; } @@ -479,8 +550,8 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value) return ret; } -int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; @@ -489,17 +560,20 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - err = reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (err) { return err; } } - return 0; + return UC_ERR_OK; } -int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; @@ -508,7 +582,7 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - err = reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } @@ -519,12 +593,12 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUARMState *env = (CPUARMState *)ctx->data; int i; @@ -533,18 +607,21 @@ int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - err = reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (err) { return err; } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUARMState *env = (CPUARMState *)ctx->data; int i; @@ -553,13 +630,13 @@ int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs, for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - err = reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); if (err) { return err; } } - return 0; + return UC_ERR_OK; } static bool arm_stop_interrupt(struct uc_struct *uc, int intno) diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index 540ebd96..24d85754 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -211,9 +211,11 @@ static int x86_msr_write(CPUX86State *env, uc_x86_msr *msr) return 0; } -static void reg_read(CPUX86State *env, unsigned int regid, void *value, - uc_mode mode) +static uc_err reg_read(CPUX86State *env, unsigned int regid, void *value, + size_t *size, uc_mode mode) { + uc_err ret = UC_ERR_ARG; + switch (regid) { default: break; @@ -225,22 +227,26 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_FP5: case UC_X86_REG_FP6: case UC_X86_REG_FP7: { + CHECK_REG_TYPE(char[10]); floatx80 reg = env->fpregs[regid - UC_X86_REG_FP0].d; cpu_get_fp80(value, (uint16_t *)((char *)value + sizeof(uint64_t)), reg); + return ret; } - return; case UC_X86_REG_FPSW: { + CHECK_REG_TYPE(uint16_t); uint16_t fpus = env->fpus; fpus = fpus & ~0x3800; fpus |= (env->fpstt & 0x7) << 11; *(uint16_t *)value = fpus; + return ret; } - return; case UC_X86_REG_FPCW: + CHECK_REG_TYPE(uint16_t); *(uint16_t *)value = env->fpuc; - return; + return ret; case UC_X86_REG_FPTAG: { + CHECK_REG_TYPE(uint16_t); #define EXPD(fp) (fp.l.upper & 0x7fff) #define MANTD(fp) (fp.l.lower) #define MAXEXPD 0x7fff @@ -267,8 +273,8 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, } } *(uint16_t *)value = fptag; + return ret; } - return; case UC_X86_REG_XMM0: case UC_X86_REG_XMM1: case UC_X86_REG_XMM2: @@ -277,11 +283,12 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_XMM5: case UC_X86_REG_XMM6: case UC_X86_REG_XMM7: { + CHECK_REG_TYPE(float64[2]); float64 *dst = (float64 *)value; ZMMReg *reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_XMM0]; dst[0] = reg->ZMM_Q(0); dst[1] = reg->ZMM_Q(1); - return; + return ret; } case UC_X86_REG_ST0: case UC_X86_REG_ST1: @@ -291,9 +298,9 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_ST5: case UC_X86_REG_ST6: case UC_X86_REG_ST7: { - // value must be big enough to keep 80 bits (10 bytes) + CHECK_REG_TYPE(char[10]); memcpy(value, &FPST(regid - UC_X86_REG_ST0), 10); - return; + return ret; } case UC_X86_REG_YMM0: case UC_X86_REG_YMM1: @@ -311,6 +318,7 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_YMM13: case UC_X86_REG_YMM14: case UC_X86_REG_YMM15: { + CHECK_REG_TYPE(float64[4]); float64 *dst = (float64 *)value; ZMMReg *lo_reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_YMM0]; XMMReg *hi_reg = &env->ymmh_regs[regid - UC_X86_REG_YMM0]; @@ -318,24 +326,29 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, dst[1] = lo_reg->ZMM_Q(1); dst[2] = hi_reg->_d[0]; dst[3] = hi_reg->_d[1]; - return; + return ret; } case UC_X86_REG_FIP: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->fpip; - return; + return ret; case UC_X86_REG_FCS: + CHECK_REG_TYPE(uint16_t); *(uint16_t *)value = env->fpcs; - return; + return ret; case UC_X86_REG_FDP: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->fpdp; - return; + return ret; case UC_X86_REG_FDS: + CHECK_REG_TYPE(uint16_t); *(uint16_t *)value = env->fpds; - return; + return ret; case UC_X86_REG_FOP: + CHECK_REG_TYPE(uint16_t); *(uint16_t *)value = env->fpop; - return; + return ret; } switch (mode) { @@ -346,23 +359,29 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, default: break; case UC_X86_REG_ES: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = env->segs[R_ES].selector; - return; + return ret; case UC_X86_REG_SS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = env->segs[R_SS].selector; - return; + return ret; case UC_X86_REG_DS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = env->segs[R_DS].selector; - return; + return ret; case UC_X86_REG_FS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = env->segs[R_FS].selector; - return; + return ret; case UC_X86_REG_GS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = env->segs[R_GS].selector; - return; + return ret; case UC_X86_REG_FS_BASE: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = (uint32_t)env->segs[R_FS].base; - return; + return ret; } // fall-thru case UC_MODE_32: @@ -374,6 +393,7 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_CR2: case UC_X86_REG_CR3: case UC_X86_REG_CR4: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->cr[regid - UC_X86_REG_CR0]; break; case UC_X86_REG_DR0: @@ -384,137 +404,179 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_DR5: case UC_X86_REG_DR6: case UC_X86_REG_DR7: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->dr[regid - UC_X86_REG_DR0]; break; case UC_X86_REG_FLAGS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = cpu_compute_eflags(env); break; case UC_X86_REG_EFLAGS: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = cpu_compute_eflags(env); break; case UC_X86_REG_EAX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_EAX]; break; case UC_X86_REG_AX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EAX]); break; case UC_X86_REG_AH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EAX]); break; case UC_X86_REG_AL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EAX]); break; case UC_X86_REG_EBX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_EBX]; break; case UC_X86_REG_BX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EBX]); break; case UC_X86_REG_BH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EBX]); break; case UC_X86_REG_BL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EBX]); break; case UC_X86_REG_ECX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_ECX]; break; case UC_X86_REG_CX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ECX]); break; case UC_X86_REG_CH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_ECX]); break; case UC_X86_REG_CL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_ECX]); break; case UC_X86_REG_EDX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_EDX]; break; case UC_X86_REG_DX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EDX]); break; case UC_X86_REG_DH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EDX]); break; case UC_X86_REG_DL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EDX]); break; case UC_X86_REG_ESP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_ESP]; break; case UC_X86_REG_SP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ESP]); break; case UC_X86_REG_EBP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_EBP]; break; case UC_X86_REG_BP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EBP]); break; case UC_X86_REG_ESI: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_ESI]; break; case UC_X86_REG_SI: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ESI]); break; case UC_X86_REG_EDI: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->regs[R_EDI]; break; case UC_X86_REG_DI: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EDI]); break; case UC_X86_REG_EIP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = env->eip; break; case UC_X86_REG_IP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->eip); break; case UC_X86_REG_CS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_CS].selector; break; case UC_X86_REG_DS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_DS].selector; break; case UC_X86_REG_SS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_SS].selector; break; case UC_X86_REG_ES: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_ES].selector; break; case UC_X86_REG_FS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_FS].selector; break; case UC_X86_REG_GS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_GS].selector; break; case UC_X86_REG_IDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = (uint16_t)env->idt.limit; ((uc_x86_mmr *)value)->base = (uint32_t)env->idt.base; break; case UC_X86_REG_GDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = (uint16_t)env->gdt.limit; ((uc_x86_mmr *)value)->base = (uint32_t)env->gdt.base; break; case UC_X86_REG_LDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = env->ldt.limit; ((uc_x86_mmr *)value)->base = (uint32_t)env->ldt.base; ((uc_x86_mmr *)value)->selector = (uint16_t)env->ldt.selector; ((uc_x86_mmr *)value)->flags = env->ldt.flags; break; case UC_X86_REG_TR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = env->tr.limit; ((uc_x86_mmr *)value)->base = (uint32_t)env->tr.base; ((uc_x86_mmr *)value)->selector = (uint16_t)env->tr.selector; ((uc_x86_mmr *)value)->flags = env->tr.flags; break; case UC_X86_REG_MSR: + CHECK_REG_TYPE(uc_x86_msr); x86_msr_read(env, (uc_x86_msr *)value); break; case UC_X86_REG_MXCSR: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->mxcsr; break; case UC_X86_REG_FS_BASE: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = (uint32_t)env->segs[R_FS].base; break; } @@ -530,6 +592,7 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_CR2: case UC_X86_REG_CR3: case UC_X86_REG_CR4: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = env->cr[regid - UC_X86_REG_CR0]; break; case UC_X86_REG_DR0: @@ -540,272 +603,359 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_DR5: case UC_X86_REG_DR6: case UC_X86_REG_DR7: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = env->dr[regid - UC_X86_REG_DR0]; break; case UC_X86_REG_FLAGS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = cpu_compute_eflags(env); break; case UC_X86_REG_EFLAGS: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = cpu_compute_eflags(env); break; case UC_X86_REG_RFLAGS: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = cpu_compute_eflags(env); break; case UC_X86_REG_RAX: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_EAX]; break; case UC_X86_REG_EAX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_EAX]); break; case UC_X86_REG_AX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EAX]); break; case UC_X86_REG_AH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EAX]); break; case UC_X86_REG_AL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EAX]); break; case UC_X86_REG_RBX: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_EBX]; break; case UC_X86_REG_EBX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_EBX]); break; case UC_X86_REG_BX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EBX]); break; case UC_X86_REG_BH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EBX]); break; case UC_X86_REG_BL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EBX]); break; case UC_X86_REG_RCX: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_ECX]; break; case UC_X86_REG_ECX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_ECX]); break; case UC_X86_REG_CX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ECX]); break; case UC_X86_REG_CH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_ECX]); break; case UC_X86_REG_CL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_ECX]); break; case UC_X86_REG_RDX: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_EDX]; break; case UC_X86_REG_EDX: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_EDX]); break; case UC_X86_REG_DX: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EDX]); break; case UC_X86_REG_DH: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_H(env->regs[R_EDX]); break; case UC_X86_REG_DL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EDX]); break; case UC_X86_REG_RSP: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_ESP]; break; case UC_X86_REG_ESP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_ESP]); break; case UC_X86_REG_SP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ESP]); break; case UC_X86_REG_SPL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_ESP]); break; case UC_X86_REG_RBP: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_EBP]; break; case UC_X86_REG_EBP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_EBP]); break; case UC_X86_REG_BP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EBP]); break; case UC_X86_REG_BPL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EBP]); break; case UC_X86_REG_RSI: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_ESI]; break; case UC_X86_REG_ESI: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_ESI]); break; case UC_X86_REG_SI: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_ESI]); break; case UC_X86_REG_SIL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_ESI]); break; case UC_X86_REG_RDI: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[R_EDI]; break; case UC_X86_REG_EDI: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[R_EDI]); break; case UC_X86_REG_DI: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[R_EDI]); break; case UC_X86_REG_DIL: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[R_EDI]); break; case UC_X86_REG_RIP: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->eip; break; case UC_X86_REG_EIP: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->eip); break; case UC_X86_REG_IP: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->eip); break; case UC_X86_REG_CS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_CS].selector; break; case UC_X86_REG_DS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_DS].selector; break; case UC_X86_REG_SS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_SS].selector; break; case UC_X86_REG_ES: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_ES].selector; break; case UC_X86_REG_FS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_FS].selector; break; case UC_X86_REG_GS: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = (uint16_t)env->segs[R_GS].selector; break; case UC_X86_REG_R8: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[8]); break; case UC_X86_REG_R8D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[8]); break; case UC_X86_REG_R8W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[8]); break; case UC_X86_REG_R8B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[8]); break; case UC_X86_REG_R9: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[9]); break; case UC_X86_REG_R9D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[9]); break; case UC_X86_REG_R9W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[9]); break; case UC_X86_REG_R9B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[9]); break; case UC_X86_REG_R10: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[10]); break; case UC_X86_REG_R10D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[10]); break; case UC_X86_REG_R10W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[10]); break; case UC_X86_REG_R10B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[10]); break; case UC_X86_REG_R11: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[11]); break; case UC_X86_REG_R11D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[11]); break; case UC_X86_REG_R11W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[11]); break; case UC_X86_REG_R11B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[11]); break; case UC_X86_REG_R12: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[12]); break; case UC_X86_REG_R12D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[12]); break; case UC_X86_REG_R12W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[12]); break; case UC_X86_REG_R12B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[12]); break; case UC_X86_REG_R13: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[13]); break; case UC_X86_REG_R13D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[13]); break; case UC_X86_REG_R13W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[13]); break; case UC_X86_REG_R13B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[13]); break; case UC_X86_REG_R14: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[14]); break; case UC_X86_REG_R14D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[14]); break; case UC_X86_REG_R14W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[14]); break; case UC_X86_REG_R14B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[14]); break; case UC_X86_REG_R15: + CHECK_REG_TYPE(int64_t); *(int64_t *)value = READ_QWORD(env->regs[15]); break; case UC_X86_REG_R15D: + CHECK_REG_TYPE(int32_t); *(int32_t *)value = READ_DWORD(env->regs[15]); break; case UC_X86_REG_R15W: + CHECK_REG_TYPE(int16_t); *(int16_t *)value = READ_WORD(env->regs[15]); break; case UC_X86_REG_R15B: + CHECK_REG_TYPE(int8_t); *(int8_t *)value = READ_BYTE_L(env->regs[15]); break; case UC_X86_REG_IDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = (uint16_t)env->idt.limit; ((uc_x86_mmr *)value)->base = env->idt.base; break; case UC_X86_REG_GDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = (uint16_t)env->gdt.limit; ((uc_x86_mmr *)value)->base = env->gdt.base; break; case UC_X86_REG_LDTR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = env->ldt.limit; ((uc_x86_mmr *)value)->base = env->ldt.base; ((uc_x86_mmr *)value)->selector = (uint16_t)env->ldt.selector; ((uc_x86_mmr *)value)->flags = env->ldt.flags; break; case UC_X86_REG_TR: + CHECK_REG_TYPE(uc_x86_mmr); ((uc_x86_mmr *)value)->limit = env->tr.limit; ((uc_x86_mmr *)value)->base = env->tr.base; ((uc_x86_mmr *)value)->selector = (uint16_t)env->tr.selector; ((uc_x86_mmr *)value)->flags = env->tr.flags; break; case UC_X86_REG_MSR: + CHECK_REG_TYPE(uc_x86_msr); x86_msr_read(env, (uc_x86_msr *)value); break; case UC_X86_REG_MXCSR: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->mxcsr; break; case UC_X86_REG_XMM8: @@ -816,6 +966,7 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, case UC_X86_REG_XMM13: case UC_X86_REG_XMM14: case UC_X86_REG_XMM15: { + CHECK_REG_TYPE(float64[2]); float64 *dst = (float64 *)value; ZMMReg *reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_XMM0]; dst[0] = reg->ZMM_Q(0); @@ -823,9 +974,11 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, break; } case UC_X86_REG_FS_BASE: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = (uint64_t)env->segs[R_FS].base; break; case UC_X86_REG_GS_BASE: + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = (uint64_t)env->segs[R_GS].base; break; } @@ -833,13 +986,13 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value, #endif } - return; + return ret; } -static int reg_write(CPUX86State *env, unsigned int regid, const void *value, - uc_mode mode) +static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value, + size_t *size, uc_mode mode) { - int ret; + uc_err ret = UC_ERR_ARG; switch (regid) { default: @@ -852,21 +1005,25 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_FP5: case UC_X86_REG_FP6: case UC_X86_REG_FP7: { + CHECK_REG_TYPE(char[10]); uint64_t mant = *(uint64_t *)value; uint16_t upper = *(uint16_t *)((char *)value + sizeof(uint64_t)); env->fpregs[regid - UC_X86_REG_FP0].d = cpu_set_fp80(mant, upper); + return ret; } - return 0; case UC_X86_REG_FPSW: { + CHECK_REG_TYPE(uint16_t); uint16_t fpus = *(uint16_t *)value; env->fpus = fpus & ~0x3800; env->fpstt = (fpus >> 11) & 0x7; + return ret; } - return 0; case UC_X86_REG_FPCW: + CHECK_REG_TYPE(uint16_t); cpu_set_fpuc(env, *(uint16_t *)value); - return 0; + return ret; case UC_X86_REG_FPTAG: { + CHECK_REG_TYPE(uint16_t); int i; uint16_t fptag = *(uint16_t *)value; for (i = 0; i < 8; i++) { @@ -874,8 +1031,8 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, fptag >>= 2; } - return 0; - } break; + return ret; + } case UC_X86_REG_XMM0: case UC_X86_REG_XMM1: case UC_X86_REG_XMM2: @@ -884,11 +1041,12 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_XMM5: case UC_X86_REG_XMM6: case UC_X86_REG_XMM7: { + CHECK_REG_TYPE(float64[2]); float64 *src = (float64 *)value; ZMMReg *reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_XMM0]; reg->ZMM_Q(0) = src[0]; reg->ZMM_Q(1) = src[1]; - return 0; + return ret; } case UC_X86_REG_ST0: case UC_X86_REG_ST1: @@ -898,9 +1056,9 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_ST5: case UC_X86_REG_ST6: case UC_X86_REG_ST7: { - // value must be big enough to keep 80 bits (10 bytes) + CHECK_REG_TYPE(char[10]); memcpy(&FPST(regid - UC_X86_REG_ST0), value, 10); - return 0; + return ret; } case UC_X86_REG_YMM0: case UC_X86_REG_YMM1: @@ -918,6 +1076,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_YMM13: case UC_X86_REG_YMM14: case UC_X86_REG_YMM15: { + CHECK_REG_TYPE(float64[4]); float64 *src = (float64 *)value; ZMMReg *lo_reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_YMM0]; XMMReg *hi_reg = &env->ymmh_regs[regid - UC_X86_REG_YMM0]; @@ -927,24 +1086,29 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, // As of qemu 5.0.1, ymmh_regs is nowhere used. hi_reg->_d[0] = src[2]; hi_reg->_d[1] = src[3]; - return 0; + return ret; } case UC_X86_REG_FIP: + CHECK_REG_TYPE(uint64_t); env->fpip = *(uint64_t *)value; - return 0; + return ret; case UC_X86_REG_FCS: + CHECK_REG_TYPE(uint16_t); env->fpcs = *(uint16_t *)value; - return 0; + return ret; case UC_X86_REG_FDP: + CHECK_REG_TYPE(uint64_t); env->fpdp = *(uint64_t *)value; - return 0; + return ret; case UC_X86_REG_FDS: + CHECK_REG_TYPE(uint16_t); env->fpds = *(uint16_t *)value; - return 0; + return ret; case UC_X86_REG_FOP: + CHECK_REG_TYPE(uint16_t); env->fpop = *(uint16_t *)value; - return 0; + return ret; } switch (mode) { @@ -956,20 +1120,25 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, default: break; case UC_X86_REG_ES: + CHECK_REG_TYPE(uint16_t); load_seg_16_helper(env, R_ES, *(uint16_t *)value); - return 0; + return ret; case UC_X86_REG_SS: + CHECK_REG_TYPE(uint16_t); load_seg_16_helper(env, R_SS, *(uint16_t *)value); - return 0; + return ret; case UC_X86_REG_DS: + CHECK_REG_TYPE(uint16_t); load_seg_16_helper(env, R_DS, *(uint16_t *)value); - return 0; + return ret; case UC_X86_REG_FS: + CHECK_REG_TYPE(uint16_t); load_seg_16_helper(env, R_FS, *(uint16_t *)value); - return 0; + return ret; case UC_X86_REG_GS: + CHECK_REG_TYPE(uint16_t); load_seg_16_helper(env, R_GS, *(uint16_t *)value); - return 0; + return ret; } // fall-thru case UC_MODE_32: @@ -977,14 +1146,17 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, default: break; case UC_X86_REG_CR0: + CHECK_REG_TYPE(uint32_t); cpu_x86_update_cr0(env, *(uint32_t *)value); goto write_cr; case UC_X86_REG_CR1: case UC_X86_REG_CR2: case UC_X86_REG_CR3: + CHECK_REG_TYPE(uint32_t); cpu_x86_update_cr3(env, *(uint32_t *)value); goto write_cr; case UC_X86_REG_CR4: + CHECK_REG_TYPE(uint32_t); cpu_x86_update_cr4(env, *(uint32_t *)value); write_cr: env->cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value; @@ -997,93 +1169,123 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_DR5: case UC_X86_REG_DR6: case UC_X86_REG_DR7: + CHECK_REG_TYPE(uint32_t); env->dr[regid - UC_X86_REG_DR0] = *(uint32_t *)value; break; case UC_X86_REG_FLAGS: + CHECK_REG_TYPE(uint16_t); cpu_load_eflags(env, *(uint16_t *)value, -1); break; case UC_X86_REG_EFLAGS: + CHECK_REG_TYPE(uint32_t); cpu_load_eflags(env, *(uint32_t *)value, -1); break; case UC_X86_REG_EAX: + CHECK_REG_TYPE(uint32_t); env->regs[R_EAX] = *(uint32_t *)value; break; case UC_X86_REG_AX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EAX], *(uint16_t *)value); break; case UC_X86_REG_AH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_AL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_EBX: + CHECK_REG_TYPE(uint32_t); env->regs[R_EBX] = *(uint32_t *)value; break; case UC_X86_REG_BX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EBX], *(uint16_t *)value); break; case UC_X86_REG_BH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_BL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_ECX: + CHECK_REG_TYPE(uint32_t); env->regs[R_ECX] = *(uint32_t *)value; break; case UC_X86_REG_CX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ECX], *(uint16_t *)value); break; case UC_X86_REG_CH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_CL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_EDX: + CHECK_REG_TYPE(uint32_t); env->regs[R_EDX] = *(uint32_t *)value; break; case UC_X86_REG_DX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EDX], *(uint16_t *)value); break; case UC_X86_REG_DH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_DL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_ESP: + CHECK_REG_TYPE(uint32_t); env->regs[R_ESP] = *(uint32_t *)value; break; case UC_X86_REG_SP: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ESP], *(uint16_t *)value); break; case UC_X86_REG_EBP: + CHECK_REG_TYPE(uint32_t); env->regs[R_EBP] = *(uint32_t *)value; break; case UC_X86_REG_BP: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EBP], *(uint16_t *)value); break; case UC_X86_REG_ESI: + CHECK_REG_TYPE(uint32_t); env->regs[R_ESI] = *(uint32_t *)value; break; case UC_X86_REG_SI: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ESI], *(uint16_t *)value); break; case UC_X86_REG_EDI: + CHECK_REG_TYPE(uint32_t); env->regs[R_EDI] = *(uint32_t *)value; break; case UC_X86_REG_DI: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EDI], *(uint16_t *)value); break; case UC_X86_REG_EIP: + CHECK_REG_TYPE(uint32_t); env->eip = *(uint32_t *)value; break; case UC_X86_REG_IP: + CHECK_REG_TYPE(uint16_t); env->eip = *(uint16_t *)value; break; case UC_X86_REG_CS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_CS, *(uint16_t *)value); if (ret) { return ret; @@ -1091,6 +1293,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_CS, *(uint16_t *)value); break; case UC_X86_REG_DS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_DS, *(uint16_t *)value); if (ret) { return ret; @@ -1098,6 +1301,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_DS, *(uint16_t *)value); break; case UC_X86_REG_SS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_SS, *(uint16_t *)value); if (ret) { return ret; @@ -1105,6 +1309,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_SS, *(uint16_t *)value); break; case UC_X86_REG_ES: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_ES, *(uint16_t *)value); if (ret) { return ret; @@ -1112,6 +1317,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_ES, *(uint16_t *)value); break; case UC_X86_REG_FS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_FS, *(uint16_t *)value); if (ret) { return ret; @@ -1119,6 +1325,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_FS, *(uint16_t *)value); break; case UC_X86_REG_GS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_GS, *(uint16_t *)value); if (ret) { return ret; @@ -1126,37 +1333,45 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_GS, *(uint16_t *)value); break; case UC_X86_REG_IDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->idt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; env->idt.base = (uint32_t)((uc_x86_mmr *)value)->base; break; case UC_X86_REG_GDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->gdt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; env->gdt.base = (uint32_t)((uc_x86_mmr *)value)->base; break; case UC_X86_REG_LDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->ldt.limit = ((uc_x86_mmr *)value)->limit; env->ldt.base = (uint32_t)((uc_x86_mmr *)value)->base; env->ldt.selector = (uint16_t)((uc_x86_mmr *)value)->selector; env->ldt.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_TR: + CHECK_REG_TYPE(uc_x86_mmr); env->tr.limit = ((uc_x86_mmr *)value)->limit; env->tr.base = (uint32_t)((uc_x86_mmr *)value)->base; env->tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector; env->tr.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_MSR: + CHECK_REG_TYPE(uc_x86_msr); x86_msr_write(env, (uc_x86_msr *)value); break; case UC_X86_REG_MXCSR: + CHECK_REG_TYPE(uint32_t); cpu_set_mxcsr(env, *(uint32_t *)value); break; /* // Don't think base registers are a "thing" on x86 case UC_X86_REG_FS_BASE: + CHECK_REG_TYPE(uint32_t); env->segs[R_FS].base = *(uint32_t *)value; continue; case UC_X86_REG_GS_BASE: + CHECK_REG_TYPE(uint32_t); env->segs[R_GS].base = *(uint32_t *)value; continue; */ @@ -1169,14 +1384,17 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, default: break; case UC_X86_REG_CR0: + CHECK_REG_TYPE(uint64_t); cpu_x86_update_cr0(env, *(uint32_t *)value); goto write_cr64; case UC_X86_REG_CR1: case UC_X86_REG_CR2: case UC_X86_REG_CR3: + CHECK_REG_TYPE(uint64_t); cpu_x86_update_cr3(env, *(uint32_t *)value); goto write_cr64; case UC_X86_REG_CR4: + CHECK_REG_TYPE(uint64_t); cpu_x86_update_cr4(env, *(uint32_t *)value); write_cr64: env->cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value; @@ -1189,147 +1407,195 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_DR5: case UC_X86_REG_DR6: case UC_X86_REG_DR7: + CHECK_REG_TYPE(uint64_t); env->dr[regid - UC_X86_REG_DR0] = *(uint64_t *)value; break; case UC_X86_REG_FLAGS: + CHECK_REG_TYPE(uint16_t); cpu_load_eflags(env, *(uint16_t *)value, -1); break; case UC_X86_REG_EFLAGS: + CHECK_REG_TYPE(uint32_t); cpu_load_eflags(env, *(uint32_t *)value, -1); break; case UC_X86_REG_RFLAGS: + CHECK_REG_TYPE(uint64_t); cpu_load_eflags(env, *(uint64_t *)value, -1); break; case UC_X86_REG_RAX: + CHECK_REG_TYPE(uint64_t); env->regs[R_EAX] = *(uint64_t *)value; break; case UC_X86_REG_EAX: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_EAX], *(uint32_t *)value); break; case UC_X86_REG_AX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EAX], *(uint16_t *)value); break; case UC_X86_REG_AH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_AL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EAX], *(uint8_t *)value); break; case UC_X86_REG_RBX: + CHECK_REG_TYPE(uint64_t); env->regs[R_EBX] = *(uint64_t *)value; break; case UC_X86_REG_EBX: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_EBX], *(uint32_t *)value); break; case UC_X86_REG_BX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EBX], *(uint16_t *)value); break; case UC_X86_REG_BH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_BL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EBX], *(uint8_t *)value); break; case UC_X86_REG_RCX: + CHECK_REG_TYPE(uint64_t); env->regs[R_ECX] = *(uint64_t *)value; break; case UC_X86_REG_ECX: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_ECX], *(uint32_t *)value); break; case UC_X86_REG_CX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ECX], *(uint16_t *)value); break; case UC_X86_REG_CH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_CL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_ECX], *(uint8_t *)value); break; case UC_X86_REG_RDX: + CHECK_REG_TYPE(uint64_t); env->regs[R_EDX] = *(uint64_t *)value; break; case UC_X86_REG_EDX: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_EDX], *(uint32_t *)value); break; case UC_X86_REG_DX: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EDX], *(uint16_t *)value); break; case UC_X86_REG_DH: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_H(env->regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_DL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EDX], *(uint8_t *)value); break; case UC_X86_REG_RSP: + CHECK_REG_TYPE(uint64_t); env->regs[R_ESP] = *(uint64_t *)value; break; case UC_X86_REG_ESP: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_ESP], *(uint32_t *)value); break; case UC_X86_REG_SP: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ESP], *(uint16_t *)value); break; case UC_X86_REG_SPL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_ESP], *(uint8_t *)value); break; case UC_X86_REG_RBP: + CHECK_REG_TYPE(uint64_t); env->regs[R_EBP] = *(uint64_t *)value; break; case UC_X86_REG_EBP: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_EBP], *(uint32_t *)value); break; case UC_X86_REG_BP: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EBP], *(uint16_t *)value); break; case UC_X86_REG_BPL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EBP], *(uint8_t *)value); break; case UC_X86_REG_RSI: + CHECK_REG_TYPE(uint64_t); env->regs[R_ESI] = *(uint64_t *)value; break; case UC_X86_REG_ESI: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_ESI], *(uint32_t *)value); break; case UC_X86_REG_SI: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_ESI], *(uint16_t *)value); break; case UC_X86_REG_SIL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_ESI], *(uint8_t *)value); break; case UC_X86_REG_RDI: + CHECK_REG_TYPE(uint64_t); env->regs[R_EDI] = *(uint64_t *)value; break; case UC_X86_REG_EDI: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[R_EDI], *(uint32_t *)value); break; case UC_X86_REG_DI: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[R_EDI], *(uint16_t *)value); break; case UC_X86_REG_DIL: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[R_EDI], *(uint8_t *)value); break; case UC_X86_REG_RIP: + CHECK_REG_TYPE(uint64_t); env->eip = *(uint64_t *)value; break; case UC_X86_REG_EIP: + CHECK_REG_TYPE(uint32_t); env->eip = *(uint32_t *)value; break; case UC_X86_REG_IP: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->eip, *(uint16_t *)value); break; case UC_X86_REG_CS: + CHECK_REG_TYPE(uint16_t); env->segs[R_CS].selector = *(uint16_t *)value; break; case UC_X86_REG_DS: + CHECK_REG_TYPE(uint16_t); env->segs[R_DS].selector = *(uint16_t *)value; break; case UC_X86_REG_SS: + CHECK_REG_TYPE(uint16_t); env->segs[R_SS].selector = *(uint16_t *)value; break; case UC_X86_REG_ES: + CHECK_REG_TYPE(uint16_t); env->segs[R_ES].selector = *(uint16_t *)value; break; case UC_X86_REG_FS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_FS, *(uint16_t *)value); if (ret) { return ret; @@ -1337,6 +1603,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_FS, *(uint16_t *)value); break; case UC_X86_REG_GS: + CHECK_REG_TYPE(uint16_t); ret = uc_check_cpu_x86_load_seg(env, R_GS, *(uint16_t *)value); if (ret) { return ret; @@ -1344,125 +1611,163 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, cpu_x86_load_seg(env, R_GS, *(uint16_t *)value); break; case UC_X86_REG_R8: + CHECK_REG_TYPE(uint64_t); env->regs[8] = *(uint64_t *)value; break; case UC_X86_REG_R8D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[8], *(uint32_t *)value); break; case UC_X86_REG_R8W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[8], *(uint16_t *)value); break; case UC_X86_REG_R8B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[8], *(uint8_t *)value); break; case UC_X86_REG_R9: + CHECK_REG_TYPE(uint64_t); env->regs[9] = *(uint64_t *)value; break; case UC_X86_REG_R9D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[9], *(uint32_t *)value); break; case UC_X86_REG_R9W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[9], *(uint16_t *)value); break; case UC_X86_REG_R9B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[9], *(uint8_t *)value); break; case UC_X86_REG_R10: + CHECK_REG_TYPE(uint64_t); env->regs[10] = *(uint64_t *)value; break; case UC_X86_REG_R10D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[10], *(uint32_t *)value); break; case UC_X86_REG_R10W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[10], *(uint16_t *)value); break; case UC_X86_REG_R10B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[10], *(uint8_t *)value); break; case UC_X86_REG_R11: + CHECK_REG_TYPE(uint64_t); env->regs[11] = *(uint64_t *)value; break; case UC_X86_REG_R11D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[11], *(uint32_t *)value); break; case UC_X86_REG_R11W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[11], *(uint16_t *)value); break; case UC_X86_REG_R11B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[11], *(uint8_t *)value); break; case UC_X86_REG_R12: + CHECK_REG_TYPE(uint64_t); env->regs[12] = *(uint64_t *)value; break; case UC_X86_REG_R12D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[12], *(uint32_t *)value); break; case UC_X86_REG_R12W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[12], *(uint16_t *)value); break; case UC_X86_REG_R12B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[12], *(uint8_t *)value); break; case UC_X86_REG_R13: + CHECK_REG_TYPE(uint64_t); env->regs[13] = *(uint64_t *)value; break; case UC_X86_REG_R13D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[13], *(uint32_t *)value); break; case UC_X86_REG_R13W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[13], *(uint16_t *)value); break; case UC_X86_REG_R13B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[13], *(uint8_t *)value); break; case UC_X86_REG_R14: + CHECK_REG_TYPE(uint64_t); env->regs[14] = *(uint64_t *)value; break; case UC_X86_REG_R14D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[14], *(uint32_t *)value); break; case UC_X86_REG_R14W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[14], *(uint16_t *)value); break; case UC_X86_REG_R14B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[14], *(uint8_t *)value); break; case UC_X86_REG_R15: + CHECK_REG_TYPE(uint64_t); env->regs[15] = *(uint64_t *)value; break; case UC_X86_REG_R15D: + CHECK_REG_TYPE(uint32_t); WRITE_DWORD(env->regs[15], *(uint32_t *)value); break; case UC_X86_REG_R15W: + CHECK_REG_TYPE(uint16_t); WRITE_WORD(env->regs[15], *(uint16_t *)value); break; case UC_X86_REG_R15B: + CHECK_REG_TYPE(uint8_t); WRITE_BYTE_L(env->regs[15], *(uint8_t *)value); break; case UC_X86_REG_IDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->idt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; env->idt.base = ((uc_x86_mmr *)value)->base; break; case UC_X86_REG_GDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->gdt.limit = (uint16_t)((uc_x86_mmr *)value)->limit; env->gdt.base = ((uc_x86_mmr *)value)->base; break; case UC_X86_REG_LDTR: + CHECK_REG_TYPE(uc_x86_mmr); env->ldt.limit = ((uc_x86_mmr *)value)->limit; env->ldt.base = ((uc_x86_mmr *)value)->base; env->ldt.selector = (uint16_t)((uc_x86_mmr *)value)->selector; env->ldt.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_TR: + CHECK_REG_TYPE(uc_x86_mmr); env->tr.limit = ((uc_x86_mmr *)value)->limit; env->tr.base = ((uc_x86_mmr *)value)->base; env->tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector; env->tr.flags = ((uc_x86_mmr *)value)->flags; break; case UC_X86_REG_MSR: + CHECK_REG_TYPE(uc_x86_msr); x86_msr_write(env, (uc_x86_msr *)value); break; case UC_X86_REG_MXCSR: + CHECK_REG_TYPE(uint32_t); cpu_set_mxcsr(env, *(uint32_t *)value); break; case UC_X86_REG_XMM8: @@ -1473,6 +1778,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, case UC_X86_REG_XMM13: case UC_X86_REG_XMM14: case UC_X86_REG_XMM15: { + CHECK_REG_TYPE(float64[2]); float64 *src = (float64 *)value; ZMMReg *reg = (ZMMReg *)&env->xmm_regs[regid - UC_X86_REG_XMM0]; reg->ZMM_Q(0) = src[0]; @@ -1480,9 +1786,11 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, break; } case UC_X86_REG_FS_BASE: + CHECK_REG_TYPE(uint64_t); env->segs[R_FS].base = *(uint64_t *)value; return 0; case UC_X86_REG_GS_BASE: + CHECK_REG_TYPE(uint64_t); env->segs[R_GS].base = *(uint64_t *)value; return 0; } @@ -1490,37 +1798,41 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, #endif } - return 0; + return ret; } -int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value, uc->mode); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL, uc->mode); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count) +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 i; - int ret; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - ret = reg_write(env, regid, value, uc->mode); - if (ret) { - return ret; + err = reg_write(env, regid, value, sizes ? sizes + i : NULL, uc->mode); + if (err) { + return err; } switch (uc->mode) { default: @@ -1554,43 +1866,47 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int x86_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUX86State *env = (CPUX86State *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value, ctx->mode); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL, ctx->mode); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUX86State *env = (CPUX86State *)ctx->data; int i; - int ret; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - ret = reg_write(env, regid, value, ctx->mode); - if (ret) { - return ret; + err = reg_write(env, regid, value, sizes ? sizes + i : NULL, ctx->mode); + if (err) { + return err; } } - return 0; + return UC_ERR_OK; } static bool x86_stop_interrupt(struct uc_struct *uc, int intno) diff --git a/qemu/target/i386/unicorn.h b/qemu/target/i386/unicorn.h index 7c456cfb..fe5688ad 100644 --- a/qemu/target/i386/unicorn.h +++ b/qemu/target/i386/unicorn.h @@ -6,14 +6,14 @@ #define UC_QEMU_TARGET_I386_H // functions to read & write registers -int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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 **vals, int count); + void *const *vals, size_t *sizes, int count); int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); void x86_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/m68k/unicorn.c b/qemu/target/m68k/unicorn.c index d0a091fa..414a94ce 100644 --- a/qemu/target/m68k/unicorn.c +++ b/qemu/target/m68k/unicorn.c @@ -49,71 +49,97 @@ void m68k_reg_reset(struct uc_struct *uc) env->pc = 0; } -static void reg_read(CPUM68KState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUM68KState *env, unsigned int regid, void *value, + size_t *size) { - if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) - *(int32_t *)value = env->aregs[regid - UC_M68K_REG_A0]; - else if (regid >= UC_M68K_REG_D0 && regid <= UC_M68K_REG_D7) - *(int32_t *)value = env->dregs[regid - UC_M68K_REG_D0]; - else { + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->aregs[regid - UC_M68K_REG_A0]; + } else if (regid >= UC_M68K_REG_D0 && regid <= UC_M68K_REG_D7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->dregs[regid - UC_M68K_REG_D0]; + } else { switch (regid) { default: break; case UC_M68K_REG_PC: - *(int32_t *)value = env->pc; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->pc; break; case UC_M68K_REG_SR: - *(int32_t *)value = env->sr; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->sr; break; } } + + return ret; } -static void reg_write(CPUM68KState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUM68KState *env, unsigned int regid, + const void *value, size_t *size) { - if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7) { + CHECK_REG_TYPE(uint32_t); env->aregs[regid - UC_M68K_REG_A0] = *(uint32_t *)value; - else if (regid >= UC_M68K_REG_D0 && regid <= UC_M68K_REG_D7) + } else if (regid >= UC_M68K_REG_D0 && regid <= UC_M68K_REG_D7) { + CHECK_REG_TYPE(uint32_t); env->dregs[regid - UC_M68K_REG_D0] = *(uint32_t *)value; - else { + } else { switch (regid) { default: break; case UC_M68K_REG_PC: + CHECK_REG_TYPE(uint32_t); env->pc = *(uint32_t *)value; break; case UC_M68K_REG_SR: + CHECK_REG_TYPE(uint32_t); cpu_m68k_set_sr(env, *(uint32_t *)value); break; } } + + return ret; } -int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_M68K_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -121,39 +147,47 @@ int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int m68k_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUM68KState *env = (CPUM68KState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUM68KState *env = (CPUM68KState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int m68k_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/m68k/unicorn.h b/qemu/target/m68k/unicorn.h index ebd5c310..463cfd33 100644 --- a/qemu/target/m68k/unicorn.h +++ b/qemu/target/m68k/unicorn.h @@ -5,14 +5,14 @@ #define UC_QEMU_TARGET_M68K_H // functions to read & write registers -int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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 **vals, int count); + void *const *vals, size_t *sizes, int count); int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); void m68k_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/mips/unicorn.c b/qemu/target/mips/unicorn.c index fb91e9c1..786e014d 100644 --- a/qemu/target/mips/unicorn.c +++ b/qemu/target/mips/unicorn.c @@ -59,99 +59,127 @@ void mips_reg_reset(struct uc_struct *uc) env->active_tc.PC = 0; } -static void reg_read(CPUMIPSState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUMIPSState *env, unsigned int regid, void *value, + size_t *size) { - if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) { + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->active_tc.gpr[regid - UC_MIPS_REG_0]; - else { + } else { switch (regid) { default: break; case UC_MIPS_REG_HI: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->active_tc.HI[0]; break; case UC_MIPS_REG_LO: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->active_tc.LO[0]; break; case UC_MIPS_REG_PC: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->active_tc.PC; break; case UC_MIPS_REG_CP0_CONFIG3: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->CP0_Config3; break; case UC_MIPS_REG_CP0_STATUS: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->CP0_Status; break; case UC_MIPS_REG_CP0_USERLOCAL: + CHECK_REG_TYPE(mipsreg_t); *(mipsreg_t *)value = env->active_tc.CP0_UserLocal; break; } } - return; + return ret; } -static void reg_write(CPUMIPSState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUMIPSState *env, unsigned int regid, + const void *value, size_t *size) { - if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31) { + CHECK_REG_TYPE(mipsreg_t); env->active_tc.gpr[regid - UC_MIPS_REG_0] = *(mipsreg_t *)value; - else { + } else { switch (regid) { default: break; case UC_MIPS_REG_HI: + CHECK_REG_TYPE(mipsreg_t); env->active_tc.HI[0] = *(mipsreg_t *)value; break; case UC_MIPS_REG_LO: + CHECK_REG_TYPE(mipsreg_t); env->active_tc.LO[0] = *(mipsreg_t *)value; break; case UC_MIPS_REG_PC: + CHECK_REG_TYPE(mipsreg_t); env->active_tc.PC = *(mipsreg_t *)value; break; case UC_MIPS_REG_CP0_CONFIG3: + CHECK_REG_TYPE(mipsreg_t); env->CP0_Config3 = *(mipsreg_t *)value; break; case UC_MIPS_REG_CP0_STATUS: // TODO: ALL CP0 REGS // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00090-2B-MIPS32PRA-AFP-06.02.pdf // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00582-2B-microMIPS32-AFP-05.04.pdf + CHECK_REG_TYPE(mipsreg_t); env->CP0_Status = *(mipsreg_t *)value; compute_hflags(env); break; case UC_MIPS_REG_CP0_USERLOCAL: + CHECK_REG_TYPE(mipsreg_t); env->active_tc.CP0_UserLocal = *(mipsreg_t *)value; break; } } - return; + return ret; } -int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_MIPS_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -159,69 +187,78 @@ int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + 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 **vals, int count) + void *const *vals, size_t *sizes, int count) #else int mips64el_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + 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 **vals, int count) + void *const *vals, size_t *sizes, int count) #else int mipsel_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #endif #endif { CPUMIPSState *env = (CPUMIPSState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_MIPS64 #ifdef TARGET_WORDS_BIGENDIAN int mips64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #else int mips64el_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + 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, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #else int mipsel_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #endif #endif { CPUMIPSState *env = (CPUMIPSState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int mips_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/mips/unicorn.h b/qemu/target/mips/unicorn.h index 5a806522..caaa414c 100644 --- a/qemu/target/mips/unicorn.h +++ b/qemu/target/mips/unicorn.h @@ -5,27 +5,28 @@ #define UC_QEMU_TARGET_MIPS_H // functions to read & write registers -int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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); int mips_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int mips_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int mipsel_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int mipsel_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int mips64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int mips64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int mips64el_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int mips64el_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, + int count); void mips_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/ppc/unicorn.c b/qemu/target/ppc/unicorn.c index b3e75f7d..b0f02ce2 100644 --- a/qemu/target/ppc/unicorn.c +++ b/qemu/target/ppc/unicorn.c @@ -146,64 +146,31 @@ void ppc_reg_reset(struct uc_struct *uc) } // http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Motorola_PowerPC/PowerPc/GenInfo/pemch2.pdf -static void reg_read(CPUPPCState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUPPCState *env, unsigned int regid, void *value, + size_t *size) { - uint32_t val; + uc_err ret = UC_ERR_ARG; - if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) + if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) { + CHECK_REG_TYPE(ppcreg_t); *(ppcreg_t *)value = env->gpr[regid - UC_PPC_REG_0]; - else { + } else if (regid >= UC_PPC_REG_FPR0 && regid <= UC_PPC_REG_FPR31) { + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0); + } else if (regid >= UC_PPC_REG_CR0 && regid <= UC_PPC_REG_CR7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->crf[regid - UC_PPC_REG_CR0]; + } else { switch (regid) { default: break; case UC_PPC_REG_PC: + CHECK_REG_TYPE(ppcreg_t); *(ppcreg_t *)value = env->nip; break; - case UC_PPC_REG_FPR0: - case UC_PPC_REG_FPR1: - case UC_PPC_REG_FPR2: - case UC_PPC_REG_FPR3: - case UC_PPC_REG_FPR4: - case UC_PPC_REG_FPR5: - case UC_PPC_REG_FPR6: - case UC_PPC_REG_FPR7: - case UC_PPC_REG_FPR8: - case UC_PPC_REG_FPR9: - case UC_PPC_REG_FPR10: - case UC_PPC_REG_FPR11: - case UC_PPC_REG_FPR12: - case UC_PPC_REG_FPR13: - case UC_PPC_REG_FPR14: - case UC_PPC_REG_FPR15: - case UC_PPC_REG_FPR16: - case UC_PPC_REG_FPR17: - case UC_PPC_REG_FPR18: - case UC_PPC_REG_FPR19: - case UC_PPC_REG_FPR20: - case UC_PPC_REG_FPR21: - case UC_PPC_REG_FPR22: - case UC_PPC_REG_FPR23: - case UC_PPC_REG_FPR24: - case UC_PPC_REG_FPR25: - case UC_PPC_REG_FPR26: - case UC_PPC_REG_FPR27: - case UC_PPC_REG_FPR28: - case UC_PPC_REG_FPR29: - case UC_PPC_REG_FPR30: - case UC_PPC_REG_FPR31: - *(uint64_t *)value = env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0); - break; - case UC_PPC_REG_CR0: - case UC_PPC_REG_CR1: - case UC_PPC_REG_CR2: - case UC_PPC_REG_CR3: - case UC_PPC_REG_CR4: - case UC_PPC_REG_CR5: - case UC_PPC_REG_CR6: - case UC_PPC_REG_CR7: - *(uint32_t *)value = env->crf[regid - UC_PPC_REG_CR0]; - break; - case UC_PPC_REG_CR: + case UC_PPC_REG_CR: { + CHECK_REG_TYPE(uint32_t); + uint32_t val; val = 0; for (int i = 0; i < 8; i++) { val <<= 4; @@ -211,138 +178,124 @@ static void reg_read(CPUPPCState *env, unsigned int regid, void *value) } *(uint32_t *)value = val; break; + } case UC_PPC_REG_LR: + CHECK_REG_TYPE(ppcreg_t); *(ppcreg_t *)value = env->lr; break; case UC_PPC_REG_CTR: + CHECK_REG_TYPE(ppcreg_t); *(ppcreg_t *)value = env->ctr; break; case UC_PPC_REG_MSR: + CHECK_REG_TYPE(ppcreg_t); *(ppcreg_t *)value = env->msr; break; case UC_PPC_REG_XER: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->xer; break; case UC_PPC_REG_FPSCR: + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->fpscr; break; } } - return; + return ret; } -static void reg_write(CPUPPCState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value, + size_t *size) { - uint32_t val; int i; + uc_err ret = UC_ERR_ARG; - if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) + if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) { + CHECK_REG_TYPE(ppcreg_t); env->gpr[regid - UC_PPC_REG_0] = *(ppcreg_t *)value; - else { + } else if (regid >= UC_PPC_REG_FPR0 && regid <= UC_PPC_REG_FPR31) { + CHECK_REG_TYPE(uint64_t); + env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0) = *(uint64_t *)value; + } else if (regid >= UC_PPC_REG_CR0 && regid <= UC_PPC_REG_CR7) { + CHECK_REG_TYPE(uint32_t); + env->crf[regid - UC_PPC_REG_CR0] = (*(uint32_t *)value) & 0b1111; + } else { switch (regid) { default: break; case UC_PPC_REG_PC: + CHECK_REG_TYPE(ppcreg_t); env->nip = *(ppcreg_t *)value; break; - case UC_PPC_REG_FPR0: - case UC_PPC_REG_FPR1: - case UC_PPC_REG_FPR2: - case UC_PPC_REG_FPR3: - case UC_PPC_REG_FPR4: - case UC_PPC_REG_FPR5: - case UC_PPC_REG_FPR6: - case UC_PPC_REG_FPR7: - case UC_PPC_REG_FPR8: - case UC_PPC_REG_FPR9: - case UC_PPC_REG_FPR10: - case UC_PPC_REG_FPR11: - case UC_PPC_REG_FPR12: - case UC_PPC_REG_FPR13: - case UC_PPC_REG_FPR14: - case UC_PPC_REG_FPR15: - case UC_PPC_REG_FPR16: - case UC_PPC_REG_FPR17: - case UC_PPC_REG_FPR18: - case UC_PPC_REG_FPR19: - case UC_PPC_REG_FPR20: - case UC_PPC_REG_FPR21: - case UC_PPC_REG_FPR22: - case UC_PPC_REG_FPR23: - case UC_PPC_REG_FPR24: - case UC_PPC_REG_FPR25: - case UC_PPC_REG_FPR26: - case UC_PPC_REG_FPR27: - case UC_PPC_REG_FPR28: - case UC_PPC_REG_FPR29: - case UC_PPC_REG_FPR30: - case UC_PPC_REG_FPR31: - env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0) = *(uint64_t *)value; - break; - case UC_PPC_REG_CR0: - case UC_PPC_REG_CR1: - case UC_PPC_REG_CR2: - case UC_PPC_REG_CR3: - case UC_PPC_REG_CR4: - case UC_PPC_REG_CR5: - case UC_PPC_REG_CR6: - case UC_PPC_REG_CR7: - env->crf[regid - UC_PPC_REG_CR0] = (*(uint32_t *)value) & 0b1111; - break; - case UC_PPC_REG_CR: - val = *(uint32_t *)value; + case UC_PPC_REG_CR: { + CHECK_REG_TYPE(uint32_t); + uint32_t val = *(uint32_t *)value; for (i = 7; i >= 0; i--) { env->crf[i] = val & 0b1111; val >>= 4; } break; + } case UC_PPC_REG_LR: + CHECK_REG_TYPE(ppcreg_t); env->lr = *(ppcreg_t *)value; break; case UC_PPC_REG_CTR: + CHECK_REG_TYPE(ppcreg_t); env->ctr = *(ppcreg_t *)value; break; case UC_PPC_REG_MSR: + CHECK_REG_TYPE(ppcreg_t); uc_ppc_store_msr(env, *(ppcreg_t *)value, 0); break; case UC_PPC_REG_XER: + CHECK_REG_TYPE(uint32_t); env->xer = *(uint32_t *)value; break; case UC_PPC_REG_FPSCR: + CHECK_REG_TYPE(uint32_t); store_fpscr(env, *(uint32_t *)value, 0xffffffff); break; } } - return; + return ret; } -int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_PPC_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -350,49 +303,57 @@ int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_PPC64 int ppc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #else int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #endif { CPUPPCState *env = (CPUPPCState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_PPC64 int ppc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #else int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #endif { CPUPPCState *env = (CPUPPCState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } PowerPCCPU *cpu_ppc_init(struct uc_struct *uc); diff --git a/qemu/target/ppc/unicorn.h b/qemu/target/ppc/unicorn.h index 2afaa3a0..df1d901f 100644 --- a/qemu/target/ppc/unicorn.h +++ b/qemu/target/ppc/unicorn.h @@ -5,19 +5,19 @@ #define UC_QEMU_TARGET_PPC_H // functions to read & write registers -int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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); int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int ppc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int ppc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); void ppc_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/riscv/unicorn.c b/qemu/target/riscv/unicorn.c index 8970051e..846d2c17 100644 --- a/qemu/target/riscv/unicorn.c +++ b/qemu/target/riscv/unicorn.c @@ -44,6 +44,7 @@ static int csrno_map[] = { CSR_HIP, CSR_HTINST, CSR_HGATP, CSR_HTIMEDELTA, CSR_HTIMEDELTAH, }; +#define csrno_count (sizeof(csrno_map) / sizeof(int)) RISCVCPU *cpu_riscv_init(struct uc_struct *uc); @@ -78,485 +79,134 @@ static void riscv_release(void *ctx) void riscv_reg_reset(struct uc_struct *uc) {} -static void reg_read(CPURISCVState *env, unsigned int regid, void *value) +static uc_err reg_read(CPURISCVState *env, unsigned int regid, void *value, + size_t *size) { - switch (regid) { - case UC_RISCV_REG_X0: - case UC_RISCV_REG_X1: - case UC_RISCV_REG_X2: - case UC_RISCV_REG_X3: - case UC_RISCV_REG_X4: - case UC_RISCV_REG_X5: - case UC_RISCV_REG_X6: - case UC_RISCV_REG_X7: - case UC_RISCV_REG_X8: - case UC_RISCV_REG_X9: - case UC_RISCV_REG_X10: - case UC_RISCV_REG_X11: - case UC_RISCV_REG_X12: - case UC_RISCV_REG_X13: - case UC_RISCV_REG_X14: - case UC_RISCV_REG_X15: - case UC_RISCV_REG_X16: - case UC_RISCV_REG_X17: - case UC_RISCV_REG_X18: - case UC_RISCV_REG_X19: - case UC_RISCV_REG_X20: - case UC_RISCV_REG_X21: - case UC_RISCV_REG_X22: - case UC_RISCV_REG_X23: - case UC_RISCV_REG_X24: - case UC_RISCV_REG_X25: - case UC_RISCV_REG_X26: - case UC_RISCV_REG_X27: - case UC_RISCV_REG_X28: - case UC_RISCV_REG_X29: - case UC_RISCV_REG_X30: - case UC_RISCV_REG_X31: -#ifdef TARGET_RISCV64 - *(int64_t *)value = env->gpr[regid - UC_RISCV_REG_X0]; -#else - *(int32_t *)value = env->gpr[regid - UC_RISCV_REG_X0]; -#endif - break; - case UC_RISCV_REG_PC: -#ifdef TARGET_RISCV64 - *(int64_t *)value = env->pc; -#else - *(int32_t *)value = env->pc; -#endif - break; + uc_err ret = UC_ERR_ARG; - case UC_RISCV_REG_F0: // "ft0" - case UC_RISCV_REG_F1: // "ft1" - case UC_RISCV_REG_F2: // "ft2" - case UC_RISCV_REG_F3: // "ft3" - case UC_RISCV_REG_F4: // "ft4" - case UC_RISCV_REG_F5: // "ft5" - case UC_RISCV_REG_F6: // "ft6" - case UC_RISCV_REG_F7: // "ft7" - case UC_RISCV_REG_F8: // "fs0" - case UC_RISCV_REG_F9: // "fs1" - case UC_RISCV_REG_F10: // "fa0" - case UC_RISCV_REG_F11: // "fa1" - case UC_RISCV_REG_F12: // "fa2" - case UC_RISCV_REG_F13: // "fa3" - case UC_RISCV_REG_F14: // "fa4" - case UC_RISCV_REG_F15: // "fa5" - case UC_RISCV_REG_F16: // "fa6" - case UC_RISCV_REG_F17: // "fa7" - case UC_RISCV_REG_F18: // "fs2" - case UC_RISCV_REG_F19: // "fs3" - case UC_RISCV_REG_F20: // "fs4" - case UC_RISCV_REG_F21: // "fs5" - case UC_RISCV_REG_F22: // "fs6" - case UC_RISCV_REG_F23: // "fs7" - case UC_RISCV_REG_F24: // "fs8" - case UC_RISCV_REG_F25: // "fs9" - case UC_RISCV_REG_F26: // "fs10" - case UC_RISCV_REG_F27: // "fs11" - case UC_RISCV_REG_F28: // "ft8" - case UC_RISCV_REG_F29: // "ft9" - case UC_RISCV_REG_F30: // "ft10" - case UC_RISCV_REG_F31: // "ft11" + if (regid >= UC_RISCV_REG_X0 && regid <= UC_RISCV_REG_X31) { #ifdef TARGET_RISCV64 - *(int64_t *)value = env->fpr[regid - UC_RISCV_REG_F0]; + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->gpr[regid - UC_RISCV_REG_X0]; #else - *(int32_t *)value = env->fpr[regid - UC_RISCV_REG_F0]; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr[regid - UC_RISCV_REG_X0]; #endif - break; - case UC_RISCV_REG_USTATUS: - case UC_RISCV_REG_UIE: - case UC_RISCV_REG_UTVEC: - case UC_RISCV_REG_USCRATCH: - case UC_RISCV_REG_UEPC: - case UC_RISCV_REG_UCAUSE: - case UC_RISCV_REG_UTVAL: - case UC_RISCV_REG_UIP: - case UC_RISCV_REG_FFLAGS: - case UC_RISCV_REG_FRM: - case UC_RISCV_REG_FCSR: - case UC_RISCV_REG_CYCLE: - case UC_RISCV_REG_TIME: - case UC_RISCV_REG_INSTRET: - case UC_RISCV_REG_HPMCOUNTER3: - case UC_RISCV_REG_HPMCOUNTER4: - case UC_RISCV_REG_HPMCOUNTER5: - case UC_RISCV_REG_HPMCOUNTER6: - case UC_RISCV_REG_HPMCOUNTER7: - case UC_RISCV_REG_HPMCOUNTER8: - case UC_RISCV_REG_HPMCOUNTER9: - case UC_RISCV_REG_HPMCOUNTER10: - case UC_RISCV_REG_HPMCOUNTER11: - case UC_RISCV_REG_HPMCOUNTER12: - case UC_RISCV_REG_HPMCOUNTER13: - case UC_RISCV_REG_HPMCOUNTER14: - case UC_RISCV_REG_HPMCOUNTER15: - case UC_RISCV_REG_HPMCOUNTER16: - case UC_RISCV_REG_HPMCOUNTER17: - case UC_RISCV_REG_HPMCOUNTER18: - case UC_RISCV_REG_HPMCOUNTER19: - case UC_RISCV_REG_HPMCOUNTER20: - case UC_RISCV_REG_HPMCOUNTER21: - case UC_RISCV_REG_HPMCOUNTER22: - case UC_RISCV_REG_HPMCOUNTER23: - case UC_RISCV_REG_HPMCOUNTER24: - case UC_RISCV_REG_HPMCOUNTER25: - case UC_RISCV_REG_HPMCOUNTER26: - case UC_RISCV_REG_HPMCOUNTER27: - case UC_RISCV_REG_HPMCOUNTER28: - case UC_RISCV_REG_HPMCOUNTER29: - case UC_RISCV_REG_HPMCOUNTER30: - case UC_RISCV_REG_HPMCOUNTER31: - case UC_RISCV_REG_CYCLEH: - case UC_RISCV_REG_TIMEH: - case UC_RISCV_REG_INSTRETH: - case UC_RISCV_REG_HPMCOUNTER3H: - case UC_RISCV_REG_HPMCOUNTER4H: - case UC_RISCV_REG_HPMCOUNTER5H: - case UC_RISCV_REG_HPMCOUNTER6H: - case UC_RISCV_REG_HPMCOUNTER7H: - case UC_RISCV_REG_HPMCOUNTER8H: - case UC_RISCV_REG_HPMCOUNTER9H: - case UC_RISCV_REG_HPMCOUNTER10H: - case UC_RISCV_REG_HPMCOUNTER11H: - case UC_RISCV_REG_HPMCOUNTER12H: - case UC_RISCV_REG_HPMCOUNTER13H: - case UC_RISCV_REG_HPMCOUNTER14H: - case UC_RISCV_REG_HPMCOUNTER15H: - case UC_RISCV_REG_HPMCOUNTER16H: - case UC_RISCV_REG_HPMCOUNTER17H: - case UC_RISCV_REG_HPMCOUNTER18H: - case UC_RISCV_REG_HPMCOUNTER19H: - case UC_RISCV_REG_HPMCOUNTER20H: - case UC_RISCV_REG_HPMCOUNTER21H: - case UC_RISCV_REG_HPMCOUNTER22H: - case UC_RISCV_REG_HPMCOUNTER23H: - case UC_RISCV_REG_HPMCOUNTER24H: - case UC_RISCV_REG_HPMCOUNTER25H: - case UC_RISCV_REG_HPMCOUNTER26H: - case UC_RISCV_REG_HPMCOUNTER27H: - case UC_RISCV_REG_HPMCOUNTER28H: - case UC_RISCV_REG_HPMCOUNTER29H: - case UC_RISCV_REG_HPMCOUNTER30H: - case UC_RISCV_REG_HPMCOUNTER31H: - case UC_RISCV_REG_MCYCLE: - case UC_RISCV_REG_MINSTRET: - case UC_RISCV_REG_MCYCLEH: - case UC_RISCV_REG_MINSTRETH: - case UC_RISCV_REG_MVENDORID: - case UC_RISCV_REG_MARCHID: - case UC_RISCV_REG_MIMPID: - case UC_RISCV_REG_MHARTID: - case UC_RISCV_REG_MSTATUS: - case UC_RISCV_REG_MISA: - case UC_RISCV_REG_MEDELEG: - case UC_RISCV_REG_MIDELEG: - case UC_RISCV_REG_MIE: - case UC_RISCV_REG_MTVEC: - case UC_RISCV_REG_MCOUNTEREN: - case UC_RISCV_REG_MSTATUSH: - case UC_RISCV_REG_MUCOUNTEREN: - case UC_RISCV_REG_MSCOUNTEREN: - case UC_RISCV_REG_MHCOUNTEREN: - case UC_RISCV_REG_MSCRATCH: - case UC_RISCV_REG_MEPC: - case UC_RISCV_REG_MCAUSE: - case UC_RISCV_REG_MTVAL: - case UC_RISCV_REG_MIP: - case UC_RISCV_REG_MBADADDR: - case UC_RISCV_REG_SSTATUS: - case UC_RISCV_REG_SEDELEG: - case UC_RISCV_REG_SIDELEG: - case UC_RISCV_REG_SIE: - case UC_RISCV_REG_STVEC: - case UC_RISCV_REG_SCOUNTEREN: - case UC_RISCV_REG_SSCRATCH: - case UC_RISCV_REG_SEPC: - case UC_RISCV_REG_SCAUSE: - case UC_RISCV_REG_STVAL: - case UC_RISCV_REG_SIP: - case UC_RISCV_REG_SBADADDR: - case UC_RISCV_REG_SPTBR: - case UC_RISCV_REG_SATP: - case UC_RISCV_REG_HSTATUS: - case UC_RISCV_REG_HEDELEG: - case UC_RISCV_REG_HIDELEG: - case UC_RISCV_REG_HIE: - case UC_RISCV_REG_HCOUNTEREN: - case UC_RISCV_REG_HTVAL: - case UC_RISCV_REG_HIP: - case UC_RISCV_REG_HTINST: - case UC_RISCV_REG_HGATP: - case UC_RISCV_REG_HTIMEDELTA: - case UC_RISCV_REG_HTIMEDELTAH: { + } else if (regid >= UC_RISCV_REG_F0 && + regid <= UC_RISCV_REG_F31) { // "ft0".."ft31" + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->fpr[regid - UC_RISCV_REG_F0]; + } else if (regid >= UC_RISCV_REG_USTATUS && + regid < UC_RISCV_REG_USTATUS + csrno_count) { target_ulong val; int csrno = csrno_map[regid - UC_RISCV_REG_USTATUS]; riscv_csrrw(env, csrno, &val, -1, 0); #ifdef TARGET_RISCV64 + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = (uint64_t)val; #else + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = (uint32_t)val; #endif - break; - } - default: - break; + } else { + switch (regid) { + default: + break; + case UC_RISCV_REG_PC: +#ifdef TARGET_RISCV64 + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->pc; +#else + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->pc; +#endif + break; + } } - return; + return ret; } -static void reg_write(CPURISCVState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPURISCVState *env, unsigned int regid, + const void *value, size_t *size) { - switch (regid) { - case UC_RISCV_REG_X0: - case UC_RISCV_REG_X1: - case UC_RISCV_REG_X2: - case UC_RISCV_REG_X3: - case UC_RISCV_REG_X4: - case UC_RISCV_REG_X5: - case UC_RISCV_REG_X6: - case UC_RISCV_REG_X7: - case UC_RISCV_REG_X8: - case UC_RISCV_REG_X9: - case UC_RISCV_REG_X10: - case UC_RISCV_REG_X11: - case UC_RISCV_REG_X12: - case UC_RISCV_REG_X13: - case UC_RISCV_REG_X14: - case UC_RISCV_REG_X15: - case UC_RISCV_REG_X16: - case UC_RISCV_REG_X17: - case UC_RISCV_REG_X18: - case UC_RISCV_REG_X19: - case UC_RISCV_REG_X20: - case UC_RISCV_REG_X21: - case UC_RISCV_REG_X22: - case UC_RISCV_REG_X23: - case UC_RISCV_REG_X24: - case UC_RISCV_REG_X25: - case UC_RISCV_REG_X26: - case UC_RISCV_REG_X27: - case UC_RISCV_REG_X28: - case UC_RISCV_REG_X29: - case UC_RISCV_REG_X30: - case UC_RISCV_REG_X31: + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_RISCV_REG_X0 && regid <= UC_RISCV_REG_X31) { #ifdef TARGET_RISCV64 + CHECK_REG_TYPE(uint64_t); env->gpr[regid - UC_RISCV_REG_X0] = *(uint64_t *)value; #else + CHECK_REG_TYPE(uint32_t); env->gpr[regid - UC_RISCV_REG_X0] = *(uint32_t *)value; #endif - break; - case UC_RISCV_REG_PC: -#ifdef TARGET_RISCV64 - env->pc = *(uint64_t *)value; -#else - env->pc = *(uint32_t *)value; -#endif - break; - case UC_RISCV_REG_F0: // "ft0" - case UC_RISCV_REG_F1: // "ft1" - case UC_RISCV_REG_F2: // "ft2" - case UC_RISCV_REG_F3: // "ft3" - case UC_RISCV_REG_F4: // "ft4" - case UC_RISCV_REG_F5: // "ft5" - case UC_RISCV_REG_F6: // "ft6" - case UC_RISCV_REG_F7: // "ft7" - case UC_RISCV_REG_F8: // "fs0" - case UC_RISCV_REG_F9: // "fs1" - case UC_RISCV_REG_F10: // "fa0" - case UC_RISCV_REG_F11: // "fa1" - case UC_RISCV_REG_F12: // "fa2" - case UC_RISCV_REG_F13: // "fa3" - case UC_RISCV_REG_F14: // "fa4" - case UC_RISCV_REG_F15: // "fa5" - case UC_RISCV_REG_F16: // "fa6" - case UC_RISCV_REG_F17: // "fa7" - case UC_RISCV_REG_F18: // "fs2" - case UC_RISCV_REG_F19: // "fs3" - case UC_RISCV_REG_F20: // "fs4" - case UC_RISCV_REG_F21: // "fs5" - case UC_RISCV_REG_F22: // "fs6" - case UC_RISCV_REG_F23: // "fs7" - case UC_RISCV_REG_F24: // "fs8" - case UC_RISCV_REG_F25: // "fs9" - case UC_RISCV_REG_F26: // "fs10" - case UC_RISCV_REG_F27: // "fs11" - case UC_RISCV_REG_F28: // "ft8" - case UC_RISCV_REG_F29: // "ft9" - case UC_RISCV_REG_F30: // "ft10" - case UC_RISCV_REG_F31: // "ft11" -#ifdef TARGET_RISCV64 + } else if (regid >= UC_RISCV_REG_F0 && + regid <= UC_RISCV_REG_F31) { // "ft0".."ft31" + CHECK_REG_TYPE(uint64_t); env->fpr[regid - UC_RISCV_REG_F0] = *(uint64_t *)value; -#else - env->fpr[regid - UC_RISCV_REG_F0] = *(uint32_t *)value; -#endif - break; - case UC_RISCV_REG_USTATUS: - case UC_RISCV_REG_UIE: - case UC_RISCV_REG_UTVEC: - case UC_RISCV_REG_USCRATCH: - case UC_RISCV_REG_UEPC: - case UC_RISCV_REG_UCAUSE: - case UC_RISCV_REG_UTVAL: - case UC_RISCV_REG_UIP: - case UC_RISCV_REG_FFLAGS: - case UC_RISCV_REG_FRM: - case UC_RISCV_REG_FCSR: - case UC_RISCV_REG_CYCLE: - case UC_RISCV_REG_TIME: - case UC_RISCV_REG_INSTRET: - case UC_RISCV_REG_HPMCOUNTER3: - case UC_RISCV_REG_HPMCOUNTER4: - case UC_RISCV_REG_HPMCOUNTER5: - case UC_RISCV_REG_HPMCOUNTER6: - case UC_RISCV_REG_HPMCOUNTER7: - case UC_RISCV_REG_HPMCOUNTER8: - case UC_RISCV_REG_HPMCOUNTER9: - case UC_RISCV_REG_HPMCOUNTER10: - case UC_RISCV_REG_HPMCOUNTER11: - case UC_RISCV_REG_HPMCOUNTER12: - case UC_RISCV_REG_HPMCOUNTER13: - case UC_RISCV_REG_HPMCOUNTER14: - case UC_RISCV_REG_HPMCOUNTER15: - case UC_RISCV_REG_HPMCOUNTER16: - case UC_RISCV_REG_HPMCOUNTER17: - case UC_RISCV_REG_HPMCOUNTER18: - case UC_RISCV_REG_HPMCOUNTER19: - case UC_RISCV_REG_HPMCOUNTER20: - case UC_RISCV_REG_HPMCOUNTER21: - case UC_RISCV_REG_HPMCOUNTER22: - case UC_RISCV_REG_HPMCOUNTER23: - case UC_RISCV_REG_HPMCOUNTER24: - case UC_RISCV_REG_HPMCOUNTER25: - case UC_RISCV_REG_HPMCOUNTER26: - case UC_RISCV_REG_HPMCOUNTER27: - case UC_RISCV_REG_HPMCOUNTER28: - case UC_RISCV_REG_HPMCOUNTER29: - case UC_RISCV_REG_HPMCOUNTER30: - case UC_RISCV_REG_HPMCOUNTER31: - case UC_RISCV_REG_CYCLEH: - case UC_RISCV_REG_TIMEH: - case UC_RISCV_REG_INSTRETH: - case UC_RISCV_REG_HPMCOUNTER3H: - case UC_RISCV_REG_HPMCOUNTER4H: - case UC_RISCV_REG_HPMCOUNTER5H: - case UC_RISCV_REG_HPMCOUNTER6H: - case UC_RISCV_REG_HPMCOUNTER7H: - case UC_RISCV_REG_HPMCOUNTER8H: - case UC_RISCV_REG_HPMCOUNTER9H: - case UC_RISCV_REG_HPMCOUNTER10H: - case UC_RISCV_REG_HPMCOUNTER11H: - case UC_RISCV_REG_HPMCOUNTER12H: - case UC_RISCV_REG_HPMCOUNTER13H: - case UC_RISCV_REG_HPMCOUNTER14H: - case UC_RISCV_REG_HPMCOUNTER15H: - case UC_RISCV_REG_HPMCOUNTER16H: - case UC_RISCV_REG_HPMCOUNTER17H: - case UC_RISCV_REG_HPMCOUNTER18H: - case UC_RISCV_REG_HPMCOUNTER19H: - case UC_RISCV_REG_HPMCOUNTER20H: - case UC_RISCV_REG_HPMCOUNTER21H: - case UC_RISCV_REG_HPMCOUNTER22H: - case UC_RISCV_REG_HPMCOUNTER23H: - case UC_RISCV_REG_HPMCOUNTER24H: - case UC_RISCV_REG_HPMCOUNTER25H: - case UC_RISCV_REG_HPMCOUNTER26H: - case UC_RISCV_REG_HPMCOUNTER27H: - case UC_RISCV_REG_HPMCOUNTER28H: - case UC_RISCV_REG_HPMCOUNTER29H: - case UC_RISCV_REG_HPMCOUNTER30H: - case UC_RISCV_REG_HPMCOUNTER31H: - case UC_RISCV_REG_MCYCLE: - case UC_RISCV_REG_MINSTRET: - case UC_RISCV_REG_MCYCLEH: - case UC_RISCV_REG_MINSTRETH: - case UC_RISCV_REG_MVENDORID: - case UC_RISCV_REG_MARCHID: - case UC_RISCV_REG_MIMPID: - case UC_RISCV_REG_MHARTID: - case UC_RISCV_REG_MSTATUS: - case UC_RISCV_REG_MISA: - case UC_RISCV_REG_MEDELEG: - case UC_RISCV_REG_MIDELEG: - case UC_RISCV_REG_MIE: - case UC_RISCV_REG_MTVEC: - case UC_RISCV_REG_MCOUNTEREN: - case UC_RISCV_REG_MSTATUSH: - case UC_RISCV_REG_MUCOUNTEREN: - case UC_RISCV_REG_MSCOUNTEREN: - case UC_RISCV_REG_MHCOUNTEREN: - case UC_RISCV_REG_MSCRATCH: - case UC_RISCV_REG_MEPC: - case UC_RISCV_REG_MCAUSE: - case UC_RISCV_REG_MTVAL: - case UC_RISCV_REG_MIP: - case UC_RISCV_REG_MBADADDR: - case UC_RISCV_REG_SSTATUS: - case UC_RISCV_REG_SEDELEG: - case UC_RISCV_REG_SIDELEG: - case UC_RISCV_REG_SIE: - case UC_RISCV_REG_STVEC: - case UC_RISCV_REG_SCOUNTEREN: - case UC_RISCV_REG_SSCRATCH: - case UC_RISCV_REG_SEPC: - case UC_RISCV_REG_SCAUSE: - case UC_RISCV_REG_STVAL: - case UC_RISCV_REG_SIP: - case UC_RISCV_REG_SBADADDR: - case UC_RISCV_REG_SPTBR: - case UC_RISCV_REG_SATP: - case UC_RISCV_REG_HSTATUS: - case UC_RISCV_REG_HEDELEG: - case UC_RISCV_REG_HIDELEG: - case UC_RISCV_REG_HIE: - case UC_RISCV_REG_HCOUNTEREN: - case UC_RISCV_REG_HTVAL: - case UC_RISCV_REG_HIP: - case UC_RISCV_REG_HTINST: - case UC_RISCV_REG_HGATP: - case UC_RISCV_REG_HTIMEDELTA: - case UC_RISCV_REG_HTIMEDELTAH: { + } else if (regid >= UC_RISCV_REG_USTATUS && + regid < UC_RISCV_REG_USTATUS + csrno_count) { target_ulong val; int csrno = csrno_map[regid - UC_RISCV_REG_USTATUS]; #ifdef TARGET_RISCV64 + CHECK_REG_TYPE(uint64_t); riscv_csrrw(env, csrno, &val, *(uint64_t *)value, -1); #else + CHECK_REG_TYPE(uint32_t); riscv_csrrw(env, csrno, &val, *(uint32_t *)value, -1); #endif - break; - } - default: - break; + } else { + switch (regid) { + default: + break; + case UC_RISCV_REG_PC: +#ifdef TARGET_RISCV64 + CHECK_REG_TYPE(uint64_t); + env->pc = *(uint64_t *)value; +#else + CHECK_REG_TYPE(uint32_t); + env->pc = *(uint32_t *)value; +#endif + break; + } } + + return ret; } -int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_RISCV_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -564,51 +214,59 @@ int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_RISCV32 int riscv32_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #else /* TARGET_RISCV64 */ int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) #endif { CPURISCVState *env = (CPURISCVState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY #ifdef TARGET_RISCV32 int riscv32_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #else /* TARGET_RISCV64 */ int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) #endif { CPURISCVState *env = (CPURISCVState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static bool riscv_stop_interrupt(struct uc_struct *uc, int intno) diff --git a/qemu/target/riscv/unicorn.h b/qemu/target/riscv/unicorn.h index 6add9369..c7eeb450 100644 --- a/qemu/target/riscv/unicorn.h +++ b/qemu/target/riscv/unicorn.h @@ -6,19 +6,21 @@ #define UC_QEMU_TARGET_RISCV_H // functions to read & write registers -int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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); int riscv32_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int riscv32_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, + int count); int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, + int count); void riscv_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/s390x/unicorn.c b/qemu/target/s390x/unicorn.c index 6378fe4c..f2e54d02 100644 --- a/qemu/target/s390x/unicorn.c +++ b/qemu/target/s390x/unicorn.c @@ -53,80 +53,99 @@ void s390_reg_reset(struct uc_struct *uc) env->psw.addr = 0; } -static void reg_read(CPUS390XState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUS390XState *env, unsigned int regid, void *value, + size_t *size) { + uc_err ret = UC_ERR_ARG; + if (regid >= UC_S390X_REG_R0 && regid <= UC_S390X_REG_R15) { + CHECK_REG_TYPE(uint64_t); *(uint64_t *)value = env->regs[regid - UC_S390X_REG_R0]; - return; - } - - if (regid >= UC_S390X_REG_A0 && regid <= UC_S390X_REG_A15) { + } else if (regid >= UC_S390X_REG_A0 && regid <= UC_S390X_REG_A15) { + CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->regs[regid - UC_S390X_REG_A0]; - return; + } else { + switch (regid) { + default: + break; + case UC_S390X_REG_PC: + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->psw.addr; + break; + case UC_S390X_REG_PSWM: + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = get_psw_mask(env); + break; + } } - switch (regid) { - default: - break; - case UC_S390X_REG_PC: - *(uint64_t *)value = env->psw.addr; - break; - case UC_S390X_REG_PSWM: - *(uint64_t *)value = get_psw_mask(env); - break; - } + return ret; } -static void reg_write(CPUS390XState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUS390XState *env, unsigned int regid, + const void *value, size_t *size) { + uc_err ret = UC_ERR_ARG; + if (regid >= UC_S390X_REG_R0 && regid <= UC_S390X_REG_R15) { + CHECK_REG_TYPE(uint64_t); env->regs[regid - UC_S390X_REG_R0] = *(uint64_t *)value; - return; - } - - if (regid >= UC_S390X_REG_A0 && regid <= UC_S390X_REG_A15) { + } else if (regid >= UC_S390X_REG_A0 && regid <= UC_S390X_REG_A15) { + CHECK_REG_TYPE(uint32_t); env->regs[regid - UC_S390X_REG_A0] = *(uint32_t *)value; - return; - } - - switch (regid) { - default: - break; - case UC_S390X_REG_PC: - env->psw.addr = *(uint64_t *)value; - break; - case UC_S390X_REG_PSWM: - env->psw.mask = *(uint64_t *)value; - env->cc_op = (env->psw.mask >> 44) & 3; - break; + } else { + switch (regid) { + default: + break; + case UC_S390X_REG_PC: + CHECK_REG_TYPE(uint64_t); + env->psw.addr = *(uint64_t *)value; + break; + case UC_S390X_REG_PSWM: + CHECK_REG_TYPE(uint64_t); + env->psw.mask = *(uint64_t *)value; + env->cc_op = (env->psw.mask >> 44) & 3; + break; + } } + return ret; } -static int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -static int s390_reg_write(struct uc_struct *uc, unsigned int *regs, - void *const *vals, int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_S390X_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -134,39 +153,47 @@ static int s390_reg_write(struct uc_struct *uc, unsigned int *regs, } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int s390_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUS390XState *env = (CPUS390XState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUS390XState *env = (CPUS390XState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int s390_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/s390x/unicorn.h b/qemu/target/s390x/unicorn.h index 27c20653..50d507e6 100644 --- a/qemu/target/s390x/unicorn.h +++ b/qemu/target/s390x/unicorn.h @@ -5,13 +5,14 @@ #define UC_QEMU_TARGET_S390X_H // functions to read & write registers -// int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int -// count); int s390_reg_write(struct uc_struct *uc, unsigned int *regs, void -// *const *vals, int count); +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 **vals, int count); + void *const *vals, size_t *sizes, int count); int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); void s390_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/sparc/unicorn.c b/qemu/target/sparc/unicorn.c index 2df5b9b3..d000b7de 100644 --- a/qemu/target/sparc/unicorn.c +++ b/qemu/target/sparc/unicorn.c @@ -61,119 +61,149 @@ void sparc_reg_reset(struct uc_struct *uc) env->regwptr = env->regbase; } -static void reg_read(CPUSPARCState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, + size_t *size) { - if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) - *(int32_t *)value = env->gregs[regid - UC_SPARC_REG_G0]; - else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) - *(int32_t *)value = env->regwptr[regid - UC_SPARC_REG_O0]; - else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) - *(int32_t *)value = env->regwptr[8 + regid - UC_SPARC_REG_L0]; - else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) - *(int32_t *)value = env->regwptr[16 + regid - UC_SPARC_REG_I0]; - else { + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gregs[regid - UC_SPARC_REG_G0]; + } else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->regwptr[regid - UC_SPARC_REG_O0]; + } else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->regwptr[8 + regid - UC_SPARC_REG_L0]; + } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { + *(uint32_t *)value = env->regwptr[16 + regid - UC_SPARC_REG_I0]; + } else { switch (regid) { default: break; case UC_SPARC_REG_PC: - *(int32_t *)value = env->pc; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->pc; break; } } - return; + return ret; } -static void reg_write(CPUSPARCState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUSPARCState *env, unsigned int regid, + const void *value, size_t *size) { - if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { + CHECK_REG_TYPE(uint32_t); env->gregs[regid - UC_SPARC_REG_G0] = *(uint32_t *)value; - else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) + } else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) { + CHECK_REG_TYPE(uint32_t); env->regwptr[regid - UC_SPARC_REG_O0] = *(uint32_t *)value; - else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) + } else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) { + CHECK_REG_TYPE(uint32_t); env->regwptr[8 + regid - UC_SPARC_REG_L0] = *(uint32_t *)value; - else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) + } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { + CHECK_REG_TYPE(uint32_t); env->regwptr[16 + regid - UC_SPARC_REG_I0] = *(uint32_t *)value; - else { + } else { switch (regid) { default: break; case UC_SPARC_REG_PC: + CHECK_REG_TYPE(uint32_t); env->pc = *(uint32_t *)value; env->npc = *(uint32_t *)value + 4; break; } } - return; + return ret; } -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_SPARC_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); - break; + break_translation_loop(uc); } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUSPARCState *env = (CPUSPARCState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUSPARCState *env = (CPUSPARCState *)ctx->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/sparc/unicorn.h b/qemu/target/sparc/unicorn.h index 1f9818aa..62c82ba2 100644 --- a/qemu/target/sparc/unicorn.h +++ b/qemu/target/sparc/unicorn.h @@ -5,19 +5,20 @@ #define UC_QEMU_TARGET_SPARC_H // functions to read & write registers -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, - int count); +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); int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, + int count); void sparc_reg_reset(struct uc_struct *uc); diff --git a/qemu/target/sparc/unicorn64.c b/qemu/target/sparc/unicorn64.c index 5b53943f..f477ea06 100644 --- a/qemu/target/sparc/unicorn64.c +++ b/qemu/target/sparc/unicorn64.c @@ -83,103 +83,144 @@ void sparc_reg_reset(struct uc_struct *uc) env->regwptr = env->regbase; } -static void reg_read(CPUSPARCState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, size_t *size) { - if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) - *(int64_t *)value = env->gregs[regid - UC_SPARC_REG_G0]; - else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) - *(int64_t *)value = env->regwptr[regid - UC_SPARC_REG_O0]; - else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) - *(int64_t *)value = env->regwptr[8 + regid - UC_SPARC_REG_L0]; - else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) - *(int64_t *)value = env->regwptr[16 + regid - UC_SPARC_REG_I0]; - else { + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->gregs[regid - UC_SPARC_REG_G0]; + } else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) { + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->regwptr[regid - UC_SPARC_REG_O0]; + } else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) { + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->regwptr[8 + regid - UC_SPARC_REG_L0]; + } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->regwptr[16 + regid - UC_SPARC_REG_I0]; + } else { switch(regid) { - default: break; - case UC_SPARC_REG_PC: - *(int64_t *)value = env->pc; - break; + default: + break; + case UC_SPARC_REG_PC: + CHECK_REG_TYPE(uint64_t); + *(uint64_t *)value = env->pc; + break; } } + + return ret; } -static void reg_write(CPUSPARCState *env, unsigned int regid, const void *value) +static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *value, size_t *size) { - if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7) { + CHECK_REG_TYPE(uint64_t); env->gregs[regid - UC_SPARC_REG_G0] = *(uint64_t *)value; - else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) + } else if (regid >= UC_SPARC_REG_O0 && regid <= UC_SPARC_REG_O7) { + CHECK_REG_TYPE(uint64_t); env->regwptr[regid - UC_SPARC_REG_O0] = *(uint64_t *)value; - else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) + } else if (regid >= UC_SPARC_REG_L0 && regid <= UC_SPARC_REG_L7) { + CHECK_REG_TYPE(uint64_t); env->regwptr[8 + regid - UC_SPARC_REG_L0] = *(uint64_t *)value; - else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) + } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { + CHECK_REG_TYPE(uint64_t); env->regwptr[16 + regid - UC_SPARC_REG_I0] = *(uint64_t *)value; - else { + } else { switch(regid) { - default: break; - case UC_SPARC_REG_PC: - env->pc = *(uint64_t *)value; - env->npc = *(uint64_t *)value + 4; - break; + default: + break; + case UC_SPARC_REG_PC: + CHECK_REG_TYPE(uint64_t); + env->pc = *(uint64_t *)value; + env->npc = *(uint64_t *)value + 4; + break; } } + + return ret; } -int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int 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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } + if (regid == UC_SPARC_REG_PC) { + // force to quit execution and flush TB + uc->quit_request = true; + break_translation_loop(uc); + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY -int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, void **vals, int count) +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; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } DEFAULT_VISIBILITY -int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, void *const *vals, int count) +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 i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/tricore/unicorn.c b/qemu/target/tricore/unicorn.c index a3eac632..155cff15 100644 --- a/qemu/target/tricore/unicorn.c +++ b/qemu/target/tricore/unicorn.c @@ -39,193 +39,258 @@ void tricore_reg_reset(struct uc_struct *uc) env->PC = 0; } -static void reg_read(CPUTriCoreState *env, unsigned int regid, void *value) +static uc_err reg_read(CPUTriCoreState *env, unsigned int regid, void *value, + size_t *size) { - if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) - *(int32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0]; - if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15) - *(int32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0]; - else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15) - *(int32_t *)value = env->gpr_d[regid - UC_TRICORE_REG_D0]; - else { + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0]; + } else if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0]; + } else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15) { + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr_d[regid - UC_TRICORE_REG_D0]; + } else { switch (regid) { // case UC_TRICORE_REG_SP: case UC_TRICORE_REG_A10: - *(int32_t *)value = env->gpr_a[10]; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr_a[10]; break; // case UC_TRICORE_REG_LR: case UC_TRICORE_REG_A11: - *(int32_t *)value = env->gpr_a[11]; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->gpr_a[11]; break; case UC_TRICORE_REG_PC: - *(int32_t *)value = env->PC; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PC; break; case UC_TRICORE_REG_PCXI: - *(int32_t *)value = env->PCXI; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PCXI; break; case UC_TRICORE_REG_PSW: - *(int32_t *)value = env->PSW; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW; break; case UC_TRICORE_REG_PSW_USB_C: - *(int32_t *)value = env->PSW_USB_C; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW_USB_C; break; case UC_TRICORE_REG_PSW_USB_V: - *(int32_t *)value = env->PSW_USB_V; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW_USB_V; break; case UC_TRICORE_REG_PSW_USB_SV: - *(int32_t *)value = env->PSW_USB_SV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW_USB_SV; break; case UC_TRICORE_REG_PSW_USB_AV: - *(int32_t *)value = env->PSW_USB_AV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW_USB_AV; break; case UC_TRICORE_REG_PSW_USB_SAV: - *(int32_t *)value = env->PSW_USB_SAV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->PSW_USB_SAV; break; case UC_TRICORE_REG_SYSCON: - *(int32_t *)value = env->SYSCON; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->SYSCON; break; case UC_TRICORE_REG_CPU_ID: - *(int32_t *)value = env->CPU_ID; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->CPU_ID; break; case UC_TRICORE_REG_BIV: - *(int32_t *)value = env->BIV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->BIV; break; case UC_TRICORE_REG_BTV: - *(int32_t *)value = env->BTV; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->BTV; break; case UC_TRICORE_REG_ISP: - *(int32_t *)value = env->ISP; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->ISP; break; case UC_TRICORE_REG_ICR: - *(int32_t *)value = env->ICR; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->ICR; break; case UC_TRICORE_REG_FCX: - *(int32_t *)value = env->FCX; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->FCX; break; case UC_TRICORE_REG_LCX: - *(int32_t *)value = env->LCX; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->LCX; break; case UC_TRICORE_REG_COMPAT: - *(int32_t *)value = env->COMPAT; + CHECK_REG_TYPE(uint32_t); + *(uint32_t *)value = env->COMPAT; break; } } + + return ret; } -int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count) +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); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs, - void **vals, int count) + void *const *vals, size_t *sizes, int count) { CPUTriCoreState *env = (CPUTriCoreState *)uc->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; void *value = vals[i]; - reg_read(env, regid, value); + err = reg_read(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } -static void reg_write(CPUTriCoreState *env, unsigned int regid, - const void *value) +static uc_err reg_write(CPUTriCoreState *env, unsigned int regid, + const void *value, size_t *size) { - if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) - env->gpr_a[regid - UC_TRICORE_REG_A0] = *(int32_t *)value; - if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15) - env->gpr_a[regid - UC_TRICORE_REG_A0] = *(int32_t *)value; - else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15) - env->gpr_d[regid - UC_TRICORE_REG_D0] = *(int32_t *)value; - else { + uc_err ret = UC_ERR_ARG; + + if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9) { + CHECK_REG_TYPE(uint32_t); + env->gpr_a[regid - UC_TRICORE_REG_A0] = *(uint32_t *)value; + } else if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15) { + CHECK_REG_TYPE(uint32_t); + env->gpr_a[regid - UC_TRICORE_REG_A0] = *(uint32_t *)value; + } else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15) { + CHECK_REG_TYPE(uint32_t); + env->gpr_d[regid - UC_TRICORE_REG_D0] = *(uint32_t *)value; + } else { switch (regid) { // case UC_TRICORE_REG_SP: case UC_TRICORE_REG_A10: - env->gpr_a[10] = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->gpr_a[10] = *(uint32_t *)value; break; // case UC_TRICORE_REG_LR: case UC_TRICORE_REG_A11: - env->gpr_a[11] = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->gpr_a[11] = *(uint32_t *)value; break; case UC_TRICORE_REG_PC: - env->PC = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PC = *(uint32_t *)value; break; case UC_TRICORE_REG_PCXI: - env->PCXI = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PCXI = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW: - env->PSW = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW_USB_C: - env->PSW_USB_C = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW_USB_C = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW_USB_V: - env->PSW_USB_V = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW_USB_V = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW_USB_SV: - env->PSW_USB_SV = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW_USB_SV = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW_USB_AV: - env->PSW_USB_AV = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW_USB_AV = *(uint32_t *)value; break; case UC_TRICORE_REG_PSW_USB_SAV: - env->PSW_USB_SAV = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->PSW_USB_SAV = *(uint32_t *)value; break; case UC_TRICORE_REG_SYSCON: - env->SYSCON = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->SYSCON = *(uint32_t *)value; break; case UC_TRICORE_REG_CPU_ID: - env->CPU_ID = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->CPU_ID = *(uint32_t *)value; break; case UC_TRICORE_REG_BIV: - env->BIV = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->BIV = *(uint32_t *)value; break; case UC_TRICORE_REG_BTV: - env->BTV = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->BTV = *(uint32_t *)value; break; case UC_TRICORE_REG_ISP: - env->ISP = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->ISP = *(uint32_t *)value; break; case UC_TRICORE_REG_ICR: - env->ICR = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->ICR = *(uint32_t *)value; break; case UC_TRICORE_REG_FCX: - env->FCX = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->FCX = *(uint32_t *)value; break; case UC_TRICORE_REG_LCX: - env->LCX = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->LCX = *(uint32_t *)value; break; case UC_TRICORE_REG_COMPAT: - env->COMPAT = *(int32_t *)value; + CHECK_REG_TYPE(uint32_t); + env->COMPAT = *(uint32_t *)value; break; } } + + return ret; } int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env); int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; - void *value = vals[i]; - reg_write(env, regid, value); + const void *value = vals[i]; + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } if (regid == UC_TRICORE_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; @@ -233,22 +298,26 @@ int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, } } - return 0; + return UC_ERR_OK; } int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs, - void *const *vals, int count) + const void *const *vals, size_t *sizes, int count) { CPUTriCoreState *env = (CPUTriCoreState *)uc->data; int i; + uc_err err; for (i = 0; i < count; i++) { unsigned int regid = regs[i]; const void *value = vals[i]; - reg_write(env, regid, value); + err = reg_write(env, regid, value, sizes ? sizes + i : NULL); + if (err) { + return err; + } } - return 0; + return UC_ERR_OK; } static int tricore_cpus_init(struct uc_struct *uc, const char *cpu_model) diff --git a/qemu/target/tricore/unicorn.h b/qemu/target/tricore/unicorn.h index 36d30ee7..e298da05 100644 --- a/qemu/target/tricore/unicorn.h +++ b/qemu/target/tricore/unicorn.h @@ -10,15 +10,16 @@ #define UC_QEMU_TARGET_TRICORE_H // functions to read & write registers -int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, - int count); +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, - void *const *vals, int count); + const void *const *vals, size_t *sizes, int count); int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs, - void **vals, int count); + void *const *vals, size_t *sizes, int count); int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs, - void *const *vals, int count); + const void *const *vals, size_t *sizes, + int count); void tricore_reg_reset(struct uc_struct *uc); diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 98b8cf37..b5cb5610 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -128,4 +128,15 @@ static inline void uc_common_init(struct uc_struct* uc) if (!uc->release) uc->release = release_common; } + +#define CHECK_REG_TYPE(type) do { \ + if (size) { \ + if (*size < sizeof(type)) { \ + return UC_ERR_NOMEM; \ + } \ + *size = sizeof(type); \ + } \ + ret = UC_ERR_OK; \ +} while(0) + #endif diff --git a/uc.c b/uc.c index 81a89861..1152f3ee 100644 --- a/uc.c +++ b/uc.c @@ -507,47 +507,63 @@ uc_err uc_close(uc_engine *uc) UNICORN_EXPORT uc_err uc_reg_read_batch(uc_engine *uc, int *ids, void **vals, int count) { - int ret = UC_ERR_OK; - - UC_INIT(uc); - - if (uc->reg_read) { - ret = uc->reg_read(uc, (unsigned int *)ids, vals, count); - } else { - return UC_ERR_HANDLE; - } - - return ret; + return uc_reg_read_batch2(uc, ids, vals, NULL, count); } UNICORN_EXPORT uc_err uc_reg_write_batch(uc_engine *uc, int *ids, void *const *vals, int count) { - int ret = UC_ERR_OK; + return uc_reg_write_batch2(uc, ids, (const void *const *)vals, NULL, count); +} +UNICORN_EXPORT +uc_err uc_reg_read_batch2(uc_engine *uc, int *ids, void *const *vals, + size_t *sizes, int count) +{ UC_INIT(uc); - if (uc->reg_write) { - ret = uc->reg_write(uc, (unsigned int *)ids, vals, count); + if (uc->reg_read) { + return uc->reg_read(uc, (unsigned int *)ids, vals, sizes, count); } else { return UC_ERR_HANDLE; } +} - return ret; +UNICORN_EXPORT +uc_err uc_reg_write_batch2(uc_engine *uc, int *ids, const void *const *vals, + size_t *sizes, int count) +{ + UC_INIT(uc); + + if (uc->reg_write) { + return uc->reg_write(uc, (unsigned int *)ids, vals, sizes, count); + } else { + return UC_ERR_HANDLE; + } } UNICORN_EXPORT uc_err uc_reg_read(uc_engine *uc, int regid, void *value) { - UC_INIT(uc); - return uc_reg_read_batch(uc, ®id, &value, 1); + return uc_reg_read_batch2(uc, ®id, &value, NULL, 1); } UNICORN_EXPORT uc_err uc_reg_write(uc_engine *uc, int regid, const void *value) { - UC_INIT(uc); - return uc_reg_write_batch(uc, ®id, (void *const *)&value, 1); + return uc_reg_write_batch2(uc, ®id, &value, NULL, 1); +} + +UNICORN_EXPORT +uc_err uc_reg_read2(uc_engine *uc, int regid, void *value, size_t *size) +{ + return uc_reg_read_batch2(uc, ®id, &value, size, 1); +} + +UNICORN_EXPORT +uc_err uc_reg_write2(uc_engine *uc, int regid, const void *value, size_t *size) +{ + return uc_reg_write_batch2(uc, ®id, &value, size, 1); } // check if a memory area is mapped @@ -1869,13 +1885,42 @@ 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_batch(ctx, ®id, (void *const *)&value, 1); + 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_batch(ctx, ®id, &value, 1); + 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. @@ -1997,37 +2042,34 @@ static void find_context_reg_rw_function(uc_arch arch, uc_mode mode, } UNICORN_EXPORT -uc_err uc_context_reg_write_batch(uc_context *ctx, int *ids, void *const *vals, - int count) +uc_err uc_context_reg_write_batch2(uc_context *ctx, int *ids, + const void *const *vals, size_t *sizes, + int count) { - int ret = UC_ERR_OK; context_reg_rw_t rw; find_context_reg_rw_function(ctx->arch, ctx->mode, &rw); if (rw.context_reg_write) { - ret = rw.context_reg_write(ctx, (unsigned int *)ids, vals, count); + return rw.context_reg_write(ctx, (unsigned int *)ids, vals, sizes, + count); } else { return UC_ERR_HANDLE; } - - return ret; } UNICORN_EXPORT -uc_err uc_context_reg_read_batch(uc_context *ctx, int *ids, void **vals, - int count) +uc_err uc_context_reg_read_batch2(uc_context *ctx, int *ids, void *const *vals, + size_t *sizes, int count) { - int ret = UC_ERR_OK; context_reg_rw_t rw; find_context_reg_rw_function(ctx->arch, ctx->mode, &rw); if (rw.context_reg_read) { - ret = rw.context_reg_read(ctx, (unsigned int *)ids, vals, count); + return rw.context_reg_read(ctx, (unsigned int *)ids, vals, sizes, + count); } else { return UC_ERR_HANDLE; } - - return ret; } UNICORN_EXPORT