Slight refactoring to reduce code duplication.

This also comes with a performance bump due to inlining of reg_read/reg_write
(as they're only called once now) and the unlikely() on CHECK_REG_TYPE.
This commit is contained in:
Robert Xiao
2023-05-11 20:08:27 -07:00
parent 4055a5ab10
commit 074566cf69
13 changed files with 473 additions and 533 deletions

View File

@@ -268,7 +268,7 @@ static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value,
size_t *size)
size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -349,6 +349,7 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value,
case UC_ARM64_REG_PC:
CHECK_REG_TYPE(uint64_t);
env->pc = *(uint64_t *)value;
*setpc = 1;
break;
case UC_ARM64_REG_SP:
CHECK_REG_TYPE(uint64_t);
@@ -397,17 +398,15 @@ 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 *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUARMState *env, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUARMState *env = &(ARM_CPU(uc->cpu)->env);
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -416,25 +415,45 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int arm64_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUARMState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
CPUARMState *env = &(ARM_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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_ARM64_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUARMState *env = &(ARM_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int arm64_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUARMState *env = &(ARM_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -450,19 +469,7 @@ int arm64_context_reg_read(struct uc_context *ctx, unsigned int *regs,
#endif
{
CPUARMState *env = (CPUARMState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -475,19 +482,8 @@ int arm64_context_reg_write(struct uc_context *ctx, unsigned int *regs,
#endif
{
CPUARMState *env = (CPUARMState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int arm64_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -355,7 +355,7 @@ static uc_err reg_read(CPUARMState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value,
size_t *size)
size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -428,6 +428,7 @@ static uc_err reg_write(CPUARMState *env, unsigned int regid, const void *value,
env->thumb = (*(uint32_t *)value & 1);
env->uc->thumb = (*(uint32_t *)value & 1);
env->regs[15] = (*(uint32_t *)value & ~1);
*setpc = 1;
break;
// case UC_ARM_REG_C1_C0_2:
// env->cp15.c1_coproc = *(int32_t *)value;
@@ -550,20 +551,15 @@ 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 *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUARMState *env, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUARMState *env = &(ARM_CPU(uc->cpu)->env);
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -572,25 +568,45 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int arm_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUARMState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
CPUArchState *env = &(ARM_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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_ARM_REG_R15) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUARMState *env = &(ARM_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int arm_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUArchState *env = &(ARM_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -601,22 +617,7 @@ int arm_context_reg_read(struct uc_context *ctx, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUARMState *env = (CPUARMState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -624,19 +625,8 @@ int arm_context_reg_write(struct uc_context *ctx, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUARMState *env = (CPUARMState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static bool arm_stop_interrupt(struct uc_struct *uc, int intno)

View File

@@ -990,7 +990,7 @@ static uc_err reg_read(CPUX86State *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value,
size_t *size, uc_mode mode)
size_t *size, uc_mode mode, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -1279,10 +1279,12 @@ static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value,
case UC_X86_REG_EIP:
CHECK_REG_TYPE(uint32_t);
env->eip = *(uint32_t *)value;
*setpc = 1;
break;
case UC_X86_REG_IP:
CHECK_REG_TYPE(uint16_t);
env->eip = *(uint16_t *)value;
*setpc = 1;
break;
case UC_X86_REG_CS:
CHECK_REG_TYPE(uint16_t);
@@ -1569,14 +1571,17 @@ static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value,
case UC_X86_REG_RIP:
CHECK_REG_TYPE(uint64_t);
env->eip = *(uint64_t *)value;
*setpc = 1;
break;
case UC_X86_REG_EIP:
CHECK_REG_TYPE(uint32_t);
env->eip = *(uint32_t *)value;
*setpc = 1;
break;
case UC_X86_REG_IP:
CHECK_REG_TYPE(uint16_t);
WRITE_WORD(env->eip, *(uint16_t *)value);
*setpc = 1;
break;
case UC_X86_REG_CS:
CHECK_REG_TYPE(uint16_t);
@@ -1801,17 +1806,17 @@ static uc_err reg_write(CPUX86State *env, unsigned int regid, const void *value,
return ret;
}
int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUX86State *env, unsigned int *regs,
void *const *vals, size_t *sizes, int count,
int mode)
{
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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL, uc->mode);
err = reg_read(env, regid, value, sizes ? sizes + i : NULL, mode);
if (err) {
return err;
}
@@ -1820,50 +1825,47 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int x86_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUX86State *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int mode, int *setpc)
{
CPUX86State *env = &(X86_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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL, uc->mode);
err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, mode, setpc);
if (err) {
return err;
}
switch (uc->mode) {
default:
break;
case UC_MODE_32:
switch (regid) {
default:
break;
case UC_X86_REG_EIP:
case UC_X86_REG_IP:
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
break;
}
}
#ifdef TARGET_X86_64
case UC_MODE_64:
switch (regid) {
default:
break;
case UC_X86_REG_RIP:
case UC_X86_REG_EIP:
case UC_X86_REG_IP:
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
break;
}
#endif
}
return UC_ERR_OK;
}
int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUX86State *env = &(X86_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count, uc->mode);
}
int x86_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUX86State *env = &(X86_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err =
reg_write_batch(env, regs, vals, sizes, count, uc->mode, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -1874,19 +1876,7 @@ int x86_context_reg_read(struct uc_context *ctx, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUX86State *env = (CPUX86State *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL, ctx->mode);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count, ctx->mode);
}
DEFAULT_VISIBILITY
@@ -1894,19 +1884,8 @@ int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUX86State *env = (CPUX86State *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL, ctx->mode);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, ctx->mode, &setpc);
}
static bool x86_stop_interrupt(struct uc_struct *uc, int intno)

View File

@@ -79,7 +79,7 @@ static uc_err reg_read(CPUM68KState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUM68KState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -96,6 +96,7 @@ static uc_err reg_write(CPUM68KState *env, unsigned int regid,
case UC_M68K_REG_PC:
CHECK_REG_TYPE(uint32_t);
env->pc = *(uint32_t *)value;
*setpc = 1;
break;
case UC_M68K_REG_SR:
CHECK_REG_TYPE(uint32_t);
@@ -107,17 +108,15 @@ static uc_err reg_write(CPUM68KState *env, unsigned int regid,
return ret;
}
int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUM68KState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -126,25 +125,45 @@ int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int m68k_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUM68KState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_M68K_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUM68KState *env = &(M68K_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int m68k_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUM68KState *env = &(M68K_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -155,19 +174,7 @@ int m68k_context_reg_read(struct uc_context *ctx, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUM68KState *env = (CPUM68KState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -175,19 +182,8 @@ int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUM68KState *env = (CPUM68KState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int m68k_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -102,7 +102,7 @@ static uc_err reg_read(CPUMIPSState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUMIPSState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -124,6 +124,7 @@ static uc_err reg_write(CPUMIPSState *env, unsigned int regid,
case UC_MIPS_REG_PC:
CHECK_REG_TYPE(mipsreg_t);
env->active_tc.PC = *(mipsreg_t *)value;
*setpc = 1;
break;
case UC_MIPS_REG_CP0_CONFIG3:
CHECK_REG_TYPE(mipsreg_t);
@@ -147,17 +148,15 @@ static uc_err reg_write(CPUMIPSState *env, unsigned int regid,
return ret;
}
int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUMIPSState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -166,25 +165,45 @@ int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int mips_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUMIPSState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_MIPS_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUMIPSState *env = &(MIPS_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int mips_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUMIPSState *env = &(MIPS_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -210,19 +229,7 @@ int mipsel_context_reg_read(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -246,19 +253,8 @@ int mipsel_context_reg_write(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int mips_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -206,7 +206,7 @@ static uc_err reg_read(CPUPPCState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value,
size_t *size)
size_t *size, int *setpc)
{
int i;
uc_err ret = UC_ERR_ARG;
@@ -227,6 +227,7 @@ static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value,
case UC_PPC_REG_PC:
CHECK_REG_TYPE(ppcreg_t);
env->nip = *(ppcreg_t *)value;
*setpc = 1;
break;
case UC_PPC_REG_CR: {
CHECK_REG_TYPE(uint32_t);
@@ -263,17 +264,15 @@ static uc_err reg_write(CPUPPCState *env, unsigned int regid, const void *value,
return ret;
}
int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUPPCState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -282,25 +281,45 @@ int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int ppc_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUPPCState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_PPC_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUPPCState *env = &(POWERPC_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int ppc_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUPPCState *env = &(POWERPC_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -316,19 +335,7 @@ int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -341,19 +348,8 @@ int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
PowerPCCPU *cpu_ppc_init(struct uc_struct *uc);

View File

@@ -128,7 +128,7 @@ static uc_err reg_read(CPURISCVState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPURISCVState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -167,6 +167,7 @@ static uc_err reg_write(CPURISCVState *env, unsigned int regid,
CHECK_REG_TYPE(uint32_t);
env->pc = *(uint32_t *)value;
#endif
*setpc = 1;
break;
}
}
@@ -174,17 +175,15 @@ static uc_err reg_write(CPURISCVState *env, unsigned int regid,
return ret;
}
int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPURISCVState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -193,25 +192,45 @@ int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int riscv_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPURISCVState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
if (regid == UC_RISCV_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPURISCVState *env = &(RISCV_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int riscv_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPURISCVState *env = &(RISCV_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -228,19 +247,7 @@ int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -254,19 +261,8 @@ int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs,
#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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static bool riscv_stop_interrupt(struct uc_struct *uc, int intno)

View File

@@ -83,7 +83,7 @@ static uc_err reg_read(CPUS390XState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUS390XState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -100,6 +100,7 @@ static uc_err reg_write(CPUS390XState *env, unsigned int regid,
case UC_S390X_REG_PC:
CHECK_REG_TYPE(uint64_t);
env->psw.addr = *(uint64_t *)value;
*setpc = 1;
break;
case UC_S390X_REG_PSWM:
CHECK_REG_TYPE(uint64_t);
@@ -111,18 +112,34 @@ static uc_err reg_write(CPUS390XState *env, unsigned int regid,
return ret;
}
DEFAULT_VISIBILITY
int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUS390XState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
}
static uc_err reg_write_batch(CPUS390XState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
int i;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
@@ -131,26 +148,28 @@ int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
DEFAULT_VISIBILITY
int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUS390XState *env = &(S390_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
int s390_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUS390XState *env = &(S390_CPU(uc->cpu)->env);
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
if (regid == UC_S390X_REG_PC) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -161,19 +180,7 @@ int s390_context_reg_read(struct uc_context *ctx, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUS390XState *env = (CPUS390XState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -181,19 +188,8 @@ int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUS390XState *env = (CPUS390XState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int s390_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -92,7 +92,7 @@ static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value,
}
static uc_err reg_write(CPUSPARCState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -116,6 +116,7 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid,
CHECK_REG_TYPE(uint32_t);
env->pc = *(uint32_t *)value;
env->npc = *(uint32_t *)value + 4;
*setpc = 1;
break;
}
}
@@ -123,17 +124,15 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid,
return ret;
}
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
static uc_err reg_read_batch(CPUSPARCState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -142,25 +141,45 @@ int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUSPARCState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
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 UC_ERR_OK;
}
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
size_t *sizes, int count)
{
CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -171,19 +190,7 @@ int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = (CPUSPARCState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
@@ -191,19 +198,8 @@ int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = (CPUSPARCState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -113,7 +113,7 @@ static uc_err reg_read(CPUSPARCState *env, unsigned int regid, void *value, size
return ret;
}
static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *value, size_t *size)
static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -137,6 +137,7 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *valu
CHECK_REG_TYPE(uint64_t);
env->pc = *(uint64_t *)value;
env->npc = *(uint64_t *)value + 4;
*setpc = 1;
break;
}
}
@@ -144,16 +145,14 @@ static uc_err reg_write(CPUSPARCState *env, unsigned int regid, const void *valu
return ret;
}
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, size_t *sizes, int count)
static uc_err reg_read_batch(CPUSPARCState *env, 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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
@@ -162,24 +161,40 @@ int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals,
return UC_ERR_OK;
}
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, const void* const* vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUSPARCState *env, unsigned int *regs, const void* const* vals, size_t *sizes, int count, int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err = reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
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 UC_ERR_OK;
}
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, const void* const* vals, size_t *sizes, int count)
{
CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
@@ -189,38 +204,15 @@ DEFAULT_VISIBILITY
int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = (CPUSPARCState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
return reg_read_batch(env, regs, vals, sizes, count);
}
DEFAULT_VISIBILITY
int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, const void *const *vals, size_t *sizes, int count)
{
CPUSPARCState *env = (CPUSPARCState *)ctx->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int sparc_cpus_init(struct uc_struct *uc, const char *cpu_model)

View File

@@ -139,46 +139,8 @@ static uc_err reg_read(CPUTriCoreState *env, unsigned int regid, void *value,
return ret;
}
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];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
}
int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUTriCoreState *env = (CPUTriCoreState *)uc->data;
int i;
uc_err err;
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
err = reg_read(env, regid, value, sizes ? sizes + i : NULL);
if (err) {
return err;
}
}
return UC_ERR_OK;
}
static uc_err reg_write(CPUTriCoreState *env, unsigned int regid,
const void *value, size_t *size)
const void *value, size_t *size, int *setpc)
{
uc_err ret = UC_ERR_ARG;
@@ -206,6 +168,7 @@ static uc_err reg_write(CPUTriCoreState *env, unsigned int regid,
case UC_TRICORE_REG_PC:
CHECK_REG_TYPE(uint32_t);
env->PC = *(uint32_t *)value;
*setpc = 1;
break;
case UC_TRICORE_REG_PCXI:
CHECK_REG_TYPE(uint32_t);
@@ -277,41 +240,34 @@ static uc_err reg_write(CPUTriCoreState *env, unsigned int regid,
return ret;
}
int tricore_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_read_batch(CPUTriCoreState *env, 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];
const void *value = vals[i];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
void *value = vals[i];
uc_err err = reg_read(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;
break_translation_loop(uc);
}
}
return UC_ERR_OK;
}
int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
static uc_err reg_write_batch(CPUTriCoreState *env, unsigned int *regs,
const void *const *vals, size_t *sizes, int count,
int *setpc)
{
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];
err = reg_write(env, regid, value, sizes ? sizes + i : NULL);
uc_err err =
reg_write(env, regid, value, sizes ? sizes + i : NULL, setpc);
if (err) {
return err;
}
@@ -320,6 +276,46 @@ int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs,
return UC_ERR_OK;
}
int tricore_reg_read(struct uc_struct *uc, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env);
return reg_read_batch(env, regs, vals, sizes, count);
}
int tricore_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env);
int setpc = 0;
uc_err err = reg_write_batch(env, regs, vals, sizes, count, &setpc);
if (err) {
return err;
}
if (setpc) {
// force to quit execution and flush TB
uc->quit_request = true;
break_translation_loop(uc);
}
return UC_ERR_OK;
}
int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
CPUTriCoreState *env = (CPUTriCoreState *)uc->data;
return reg_read_batch(env, regs, vals, sizes, count);
}
int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
CPUTriCoreState *env = (CPUTriCoreState *)uc->data;
int setpc = 0;
return reg_write_batch(env, regs, vals, sizes, count, &setpc);
}
static int tricore_cpus_init(struct uc_struct *uc, const char *cpu_model)
{
TriCoreCPU *cpu;

View File

@@ -129,14 +129,14 @@ static inline void uc_common_init(struct uc_struct* uc)
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; \
#define CHECK_REG_TYPE(type) do { \
if (unlikely(size)) { \
if (unlikely(*size < sizeof(type))) { \
return UC_ERR_NOMEM; \
} \
*size = sizeof(type); \
} \
ret = UC_ERR_OK; \
} while(0)
#endif

47
uc.c
View File

@@ -82,6 +82,18 @@ unsigned int uc_version(unsigned int *major, unsigned int *minor)
UC_API_EXTRA;
}
static int default_reg_read(struct uc_struct *uc, unsigned int *regs,
void *const *vals, size_t *sizes, int count)
{
return UC_ERR_HANDLE;
}
static int default_reg_write(struct uc_struct *uc, unsigned int *regs,
const void *const *vals, size_t *sizes, int count)
{
return UC_ERR_HANDLE;
}
UNICORN_EXPORT
uc_err uc_errno(uc_engine *uc)
{
@@ -264,6 +276,8 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
uc->errnum = UC_ERR_OK;
uc->arch = arch;
uc->mode = mode;
uc->reg_read = default_reg_read;
uc->reg_write = default_reg_write;
// uc->ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
QLIST_INIT(&uc->ram_list.blocks);
@@ -507,13 +521,16 @@ uc_err uc_close(uc_engine *uc)
UNICORN_EXPORT
uc_err uc_reg_read_batch(uc_engine *uc, int *ids, void **vals, int count)
{
return uc_reg_read_batch2(uc, ids, vals, NULL, count);
UC_INIT(uc);
return uc->reg_read(uc, (unsigned int *)ids, vals, NULL, count);
}
UNICORN_EXPORT
uc_err uc_reg_write_batch(uc_engine *uc, int *ids, void *const *vals, int count)
{
return uc_reg_write_batch2(uc, ids, (const void *const *)vals, NULL, count);
UC_INIT(uc);
return uc->reg_write(uc, (unsigned int *)ids, (const void *const *)vals,
NULL, count);
}
UNICORN_EXPORT
@@ -521,12 +538,7 @@ 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_read) {
return uc->reg_read(uc, (unsigned int *)ids, vals, sizes, count);
} else {
return UC_ERR_HANDLE;
}
return uc->reg_read(uc, (unsigned int *)ids, vals, sizes, count);
}
UNICORN_EXPORT
@@ -534,36 +546,35 @@ 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;
}
return uc->reg_write(uc, (unsigned int *)ids, vals, sizes, count);
}
UNICORN_EXPORT
uc_err uc_reg_read(uc_engine *uc, int regid, void *value)
{
return uc_reg_read_batch2(uc, &regid, &value, NULL, 1);
UC_INIT(uc);
return uc->reg_read(uc, (unsigned int *)&regid, &value, NULL, 1);
}
UNICORN_EXPORT
uc_err uc_reg_write(uc_engine *uc, int regid, const void *value)
{
return uc_reg_write_batch2(uc, &regid, &value, NULL, 1);
UC_INIT(uc);
return uc->reg_write(uc, (unsigned int *)&regid, &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, &regid, &value, size, 1);
UC_INIT(uc);
return uc->reg_read(uc, (unsigned int *)&regid, &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, &regid, &value, size, 1);
UC_INIT(uc);
return uc->reg_write(uc, (unsigned int *)&regid, &value, size, 1);
}
// check if a memory area is mapped