v810: RzIL support (#4096)

* RzIL v810 support
* Fix v810 asm tests
* Fix analysis/v810
* v810: move ESIL formation into a separate function
* bin/elf: autodetect v810 architecture
This commit is contained in:
billow
2024-01-14 10:45:48 +08:00
committed by GitHub
parent 524fe19222
commit 02634787e9
9 changed files with 1194 additions and 296 deletions
+46
View File
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2024 billow <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef RIZIN_V810_H
#define RIZIN_V810_H
#include <rz_analysis.h>
#include <v810_disas.h>
enum {
C_BGT = 0b1111,
C_BGE = 0b1110,
C_BLT = 0b0110,
C_BLE = 0b0111,
C_BH = 0b1011,
C_BNL = 0b1001,
C_BL = 0b0001,
C_BNH = 0b0011,
C_BE = 0b0010,
C_BNE = 0b1010,
C_BV = 0b000,
C_BNV = 0b1000,
C_BN = 0b0100,
C_BP = 0b1100,
C_BC = 0b0001,
C_BNC = 0b1001,
C_BZ = 0b0010,
C_BNZ = 0b1010,
C_BR = 0b0101,
C_NOP = 0b1101,
};
typedef struct {
RzAnalysis *a;
ut16 w1;
ut16 w2;
ut32 pc;
} V810AnalysisContext;
RzAnalysisILConfig *v810_il_config(RzAnalysis *a);
RzAnalysisLiftedILOp v810_il_op(const V810AnalysisContext *a);
#endif // RIZIN_V810_H
+684
View File
@@ -0,0 +1,684 @@
// SPDX-FileCopyrightText: 2024 billow <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only
#include "v810.h"
#include <rz_il/rz_il_opbuilder_begin.h>
static const char *registers[] = {
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
"r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
"r24",
"r25",
"r26",
"r27",
"r28",
"r29",
"r30",
"r31",
"EIPC",
"EIPSW",
"FEPC",
"FEPSW",
"ECR",
"PSW",
"PIR",
"TKCW",
"Reserved_8",
"Reserved_9",
"Reserved_10",
"Reserved_11",
"Reserved_12",
"Reserved_13",
"Reserved_14",
"Reserved_15",
"Reserved_16",
"Reserved_17",
"Reserved_18",
"Reserved_19",
"Reserved_20",
"Reserved_21",
"Reserved_22",
"Reserved_23",
"CHCW",
"ADTRE",
"Reserved_26",
"Reserved_27",
"Reserved_28",
"Reserved_29",
"Reserved_30",
"Reserved_31",
NULL
};
static const char *GR[] = {
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
"r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
"r24",
"r25",
"r26",
"r27",
"r28",
"r29",
"r30",
"r31",
NULL
};
static const char **SR = registers + 32;
RzAnalysisILConfig *v810_il_config(RzAnalysis *a) {
rz_return_val_if_fail(a, NULL);
assert(RZ_STR_EQ(SR[0], "EIPC"));
RzAnalysisILConfig *cfg = rz_analysis_il_config_new(32, false, 32);
cfg->reg_bindings = registers;
return cfg;
}
static inline int32_t sext32(uint32_t X, unsigned B) {
rz_warn_if_fail(B > 0 && B <= 32);
return (int32_t)(X << (32 - B)) >> (32 - B);
}
#define COPCODE ((ctx->w1 >> 10) & 0x3F)
#define R1 (GR[((ctx->w1) & 0x1F)])
#define R2 (GR[(((ctx->w1) >> 5) & 0x1F)])
#define I5 REG1((ctx->w1))
#define I9 (ctx->w1 & 0X1FF)
#define I16 (ctx->w2)
#define I26 (ctx->w2 | ((ctx->w1 & 0x3ff) << 16))
#define CCOND (((ctx->w1) >> 9) & 0xF)
#define SUBOPC (((ctx->w2) >> 10) & 0x3F)
#define R1V VARG(R1)
#define R2V VARG(R2)
#define SEXT5 S32(sext32(I5, 5))
#define SEXT9 S32(sext32(I9, 9))
#define SEXT16 S32(sext32(I16, 16))
#define SEXT26 S32(sext32(I26, 26))
#define ZEXT5 U32(I5)
#define ZEXT9 U32(I9)
#define ZEXT16 U32(I16)
#define ZEXT26 U32(I26)
#define R1F FLOATV32(VARG(R1))
#define R2F FLOATV32(VARG(R2))
static RzILOpPure *shl0(RzILOpPure *a, RzILOpPure *b) {
return SHIFTL0(a, b);
}
static RzILOpPure *shr0(RzILOpPure *a, RzILOpPure *b) {
return SHIFTR0(a, b);
}
static RzILOpPure *fadd_(RzILOpPure *a, RzILOpPure *b) {
return FADD(0, a, b);
}
static RzILOpPure *fsub_(RzILOpPure *a, RzILOpPure *b) {
return FSUB(0, a, b);
}
static RzILOpPure *fmul_(RzILOpPure *a, RzILOpPure *b) {
return FMUL(0, a, b);
}
static RzILOpPure *fdiv_(RzILOpPure *a, RzILOpPure *b) {
return FSUB(0, a, b);
}
static RzILOpPure *bv2f32(RzILOpPure *x) {
return FLOATV32(x);
}
static RzILOpPure *f32_2int(RzILOpPure *x) {
return F2SINT(32, 0, x);
}
static RzILOpPure *f32_trunc2int(RzILOpPure *x) {
return F2SINT(32, 0, FROUND(0, x));
}
typedef struct {
const char *p;
const char *x;
unsigned i;
unsigned b;
} FLG;
static const FLG flags[] = {
{ "PSW", "RFU", 20, 12 },
{ "PSW", "I3", 19, 1 },
{ "PSW", "I2", 18, 1 },
{ "PSW", "I1", 17, 1 },
{ "PSW", "I0", 16, 1 },
{ "PSW", "NP", 15, 1 },
{ "PSW", "EP", 14, 1 },
{ "PSW", "AE", 13, 1 },
{ "PSW", "ID", 12, 1 },
{ "PSW", "RFU", 10, 2 },
{ "PSW", "FRO", 9, 1 },
{ "PSW", "FIV", 8, 1 },
{ "PSW", "FZD", 7, 1 },
{ "PSW", "FOV", 6, 1 },
{ "PSW", "FUD", 5, 1 },
{ "PSW", "FPR", 4, 1 },
{ "PSW", "CY", 3, 1 },
{ "PSW", "OV", 2, 1 },
{ "PSW", "S", 1, 1 },
{ "PSW", "Z", 0, 1 },
{ "PIR", "RFU", 16, 16 },
{ "PIR", "PT", 4, 12 },
{ "PIR", "NECRV", 0, 4 },
{ "TKCW", "RFU", 9, 24 },
{ "TKCW", "OTM", 8, 1 },
{ "TKCW", "FIT", 7, 1 },
{ "TKCW", "FZT", 6, 1 },
{ "TKCW", "FVT", 5, 1 },
{ "TKCW", "FUT", 4, 1 },
{ "TKCW", "FPT", 3, 1 },
{ "TKCW", "RDI", 2, 1 },
{ "TKCW", "RD", 0, 2 },
{ "CHCW", "SA", 8, 25 },
{ "CHCW", "CEN", 20, 12 },
{ "CHCW", "CEC", 8, 12 },
{ "CHCW", "RFU", 6, 2 },
{ "CHCW", "ICR", 5, 1 },
{ "CHCW", "ICD", 4, 1 },
{ "CHCW", "RFU", 2, 2 },
{ "CHCW", "ICE", 1, 1 },
{ "CHCW", "ICC", 0, 1 },
};
static const FLG *flag_find(const char *p, const char *x) {
for (int i = 0; i < RZ_ARRAY_SIZE(flags); ++i) {
const FLG *f = flags + i;
if (RZ_STR_NE(p, f->p)) {
continue;
}
if (RZ_STR_NE(x, f->x)) {
continue;
}
return f;
}
return NULL;
}
static RzILOpPure *VARGb(const char *p, const char *x) {
const FLG *f = flag_find(p, x);
if (!f) {
rz_warn_if_reached();
return NULL;
}
RzILOpPure *y = LET("_v_parent", VARG(p),
LOGAND(shr0(VARLP("_v_parent"), U32(f->i)), U32(f->b)));
if (f->b == 1) {
y = LET("_v_part", y,
NON_ZERO(VARLP("_v_part")));
}
return y;
}
static RzILOpEffect *SETGbs(const char *p, unsigned n, ...) {
va_list args;
va_start(args, n);
RzILOpPure *expr = NULL;
for (unsigned i = 0; i < n; ++i) {
const char *x = va_arg(args, const char *);
RzILOpPure *y = va_arg(args, RzILOpPure *);
const FLG *f = flag_find(p, x);
if (!f) {
rz_warn_if_reached();
return NULL;
}
RzILOpPure *v = shl0(f->b == 1 ? BOOL_TO_BV(y, 32) : y, U32(f->i));
expr = !expr ? v : LOGOR(expr, v);
}
return SETG(p, expr);
}
#define SETGb(p, ...) SETGbs(p, 1, __VA_ARGS__)
static RzILOpPure *overflow(RzILOpPure *x) {
return LET("_x", x,
OR(
SGT(VARLP("_x"), S32(+0x7fffffff)),
SLT(VARLP("_x"), S32(-0x80000000))));
}
static RzAnalysisLiftedILOp flags_update(const V810AnalysisContext *ctx) {
switch (COPCODE) {
case V810_NOT:
case V810_DIVU:
case V810_AND:
case V810_OR:
case V810_ORI:
case V810_XOR:
case V810_XORI:
return SETGbs("PSW", 3,
"OV", IL_FALSE,
"S", SLT(R2V, S32(0)),
"Z", IS_ZERO(R2V));
case V810_ANDI:
return SETGbs("PSW", 3,
"OV", IL_FALSE,
"S", IL_FALSE,
"Z", IS_ZERO(R2V));
case V810_DIV:
case V810_MUL:
case V810_MULU:
return SETGbs("PSW", 3,
"OV", overflow(R2V),
"S", SLT(R2V, S32(0)),
"Z", IS_ZERO(R2V));
case V810_CMP_IMM5:
return SETGbs("PSW", 4,
"CY", SLT(R2V, SEXT5),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_CMP:
case V810_SUB:
return SETGbs("PSW", 4,
"CY", SLT(R2V, R1V),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_ADD:
return SETGbs("PSW", 4,
"CY", OR(SLT(VARL("result"), R2V), SLT(VARL("result"), R1V)),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_ADD_IMM5:
return SETGbs("PSW", 4,
"CY", OR(SLT(VARL("result"), R2V), SLT(VARL("result"), SEXT5)),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_ADDI:
return SETGbs("PSW", 4,
"CY", OR(SLT(VARL("result"), SEXT16), SLT(VARL("result"), R1V)),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_SAR:
case V810_SHR:
return SETGbs("PSW", 3,
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(LOGAND(R2V, SUB(shl0(U32(1), ZEXT5), U32(1))))),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_SAR_IMM5:
case V810_SHR_IMM5:
return SETGbs("PSW", 3,
"CY", AND(NON_ZERO(R1V), NON_ZERO(LOGAND(R2V, SUB(shl0(U32(1), R1V), U32(1))))),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_SHL:
return SETGbs("PSW", 3,
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(shr0(R2V, SUB(U32(32), R1V)))),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_SHL_IMM5:
return SETGbs("PSW", 3,
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(shr0(R2V, SUB(U32(32), ZEXT5)))),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_CAXI:
return SETGbs("PSW", 4,
"CY", SLT(R2V, R1V),
"OV", overflow(VARL("result")),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V810_EXT: {
switch (SUBOPC) {
case V810_EXT_CMPF_S: return SETGbs("PSW", 4,
"OV", IL_FALSE,
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")),
"FRO", LET("_x", R2F, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
// "FPR", // 1 if degradation in precision is detected; otherwise, not affected
);
case V810_EXT_CVT_WS: return SETGbs("PSW", 5,
"CY", INV(IS_FPOS(R2F)),
"OV", IL_FALSE,
"S", FLT(R2F, F32(0)),
"Z", IS_ZERO(R2F),
"FRO", LET("_x", R2F, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
);
case V810_EXT_CVT_SW: return SETGbs("PSW", 3,
"OV", IL_FALSE,
"S", SLT(R2V, S32(0)),
"Z", IS_ZERO(R2V)
// "FRO", LET("_x", R2V, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
// ,"FIV",// TODO: invalid operation occurs
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
);
case V810_EXT_ADDF_S:
case V810_EXT_SUBF_S:
case V810_EXT_MULF_S:
case V810_EXT_DIVF_S: return SETGbs("PSW", 6,
"CY", INV(IS_FPOS(VARL("result"))),
"OV", IL_FALSE,
"S", FLT(VARL("result"), F32(0)),
"Z", IS_FZERO(VARL("result")),
"FRO", OR(IS_FNAN(VARL("result")), IS_FINF(VARL("result"))) // TODO: denormal number
// ,"FIV",// TODO: invalid operation occurs
,
"FZD", IS_FZERO(R1F)
// "FOV", // TODO: 1 if result of operation is greater than maximum normalized number that can be expressed;
// "FUD", // TODO: if result of operation is less than minimum (absolute value) normalized number that can be expressed;
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
);
case V810_EXT_XB:
case V810_EXT_XH:
case V810_EXT_REV: return NOP();
case V810_EXT_TRNC_SW: return SETGbs("PSW", 4,
"OV", IL_FALSE,
"S", FLT(FLOATV32(VARL("result")), F32(0)),
"Z", IS_FZERO(FLOATV32(VARL("result"))),
"FRO", LET("_x", FLOATV32(VARL("result")), OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
// ,"FIV",// TODO: invalid operation occurs
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
);
case V810_EXT_MPYHW:
default:
return NOP();
}
}
default:
return NOP();
}
}
typedef RzILOpPure *(*F_OP1)(RzILOpPure *);
typedef RzILOpPure *(*F_OP2)(RzILOpPure *, RzILOpPure *);
static RzAnalysisLiftedILOp lift_mov(const V810AnalysisContext *ctx, RzILOpPure *x0) {
return SETG(R2, x0);
}
static RzAnalysisLiftedILOp lift_op1(const V810AnalysisContext *ctx, RzILOpPure *x0, F_OP1 f) {
return SEQ2(
SETG(R2, f(x0)),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_op2(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
return SEQ3(
SETL("result", f(x0, x1)),
flags_update(ctx),
SETG(R2, VARL("result")));
}
static RzAnalysisLiftedILOp lift_fop1(const V810AnalysisContext *ctx, RzILOpPure *x0, F_OP1 f) {
return SEQ2(
SETG(R2, F2BV(f(x0))),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_fop2(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
return SEQ3(
SETL("result", f(x0, x1)),
flags_update(ctx),
SETG(R2, F2BV(VARL("result"))));
}
static RzAnalysisLiftedILOp lift_div(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
return SEQ3(
SETG(R2, DIV(x0, x1)),
SETG(GR[30], MOD(DUP(x0), DUP(x1))),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_mul(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
return SEQ4(
SETL("result", MUL(SIGNED(64, x0), SIGNED(64, x1))),
SETG(R2, UNSIGNED(32, VARL("result"))),
SETG(GR[30], UNSIGNED(32, shr0(VARL("result"), U32(32)))),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_mulu(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
return SEQ4(
SETL("result", MUL(UNSIGNED(64, x0), UNSIGNED(64, x1))),
SETG(R2, UNSIGNED(32, VARL("result"))),
SETG(GR[30], UNSIGNED(32, shr0(VARL("result"), U32(32)))),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_cmp(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
return SEQ2(
SETL("result", f(x0, x1)),
flags_update(ctx));
}
static RzAnalysisLiftedILOp lift_ld(const V810AnalysisContext *ctx, RzILOpPure *addr, unsigned B) {
RzILOpPure *y = LOADW(B, VARL("_adr"));
if (B == 8 || B == 16) {
y = LET("_v", UNSIGNED(32, y), SEXTRACT32(VARLP("_v"), U32(0), U32(B)));
} else {
rz_warn_if_fail(B == 32);
}
return SEQ2(
SETL("_adr", addr),
SETG(R2, y));
}
static RzAnalysisLiftedILOp lift_st(const V810AnalysisContext *ctx, RzILOpPure *addr, unsigned B) {
RzILOpPure *y = R2V;
if (B == 8 || B == 16) {
y = UNSIGNED(B, y);
} else {
rz_warn_if_fail(B == 32);
}
return SEQ2(
SETL("_adr", addr),
STOREW(VARL("_adr"), y));
}
static RzAnalysisLiftedILOp lift_reti(const V810AnalysisContext *ctx) {
return SEQ3(
SETL("_pc", ITE(VARGb("PSW", "NP"), VARG("FEPC"), VARG("EIPC"))),
SETL("PSW", ITE(VARGb("PSW", "NP"), VARG("FEPSW"), VARG("EIPSW"))),
JMP(VARL("_pc")));
}
static RzAnalysisLiftedILOp lift_jal(const V810AnalysisContext *ctx) {
return SEQ3(
SETG(GR[31], ADD(U32(ctx->pc), U32(4))),
SETL("_pc", ADD(U32(ctx->pc), SEXT26)),
JMP(VARL("_pc")));
}
static RzAnalysisLiftedILOp lift_jr(const V810AnalysisContext *ctx) {
return SEQ2(
SETL("_pc", ADD(S32(ctx->pc), SEXT26)),
JMP(VARL("_pc")));
}
static RzAnalysisLiftedILOp lift_caxi(const V810AnalysisContext *ctx) {
return SEQ5(
SETL("_adr", ADD(R1V, SEXT16)),
SETL("_tmp", LOADW(32, VARL("_adr"))),
SETL("result", SUB(R2V, VARL("_tmp"))),
flags_update(ctx),
BRANCH(IS_ZERO(VARL("result")),
SEQ2(
STOREW(VARL("_adr"), VARG(GR[30])),
SETG(R2, VARL("_tmp"))),
SEQ2(
STOREW(VARL("_adr"), VARL("_tmp")),
SETG(R2, VARL("_tmp")))));
}
static RzAnalysisLiftedILOp lift_bcond(const V810AnalysisContext *ctx, RzILOpPure *cond) {
return BRANCH(cond, SEQ2(SETL("_pc", ADD(S32(ctx->pc), SEXT9)), JMP(VARL("_pc"))), NOP());
}
RzAnalysisLiftedILOp v810_il_op(const V810AnalysisContext *ctx) {
switch (COPCODE) {
case V810_MOV: return lift_mov(ctx, R1V);
case V810_MOV_IMM5: return lift_mov(ctx, SEXT5);
case V810_MOVHI: return lift_mov(ctx, ADD(R1V, shl0(ZEXT16, U32(16))));
case V810_MOVEA: return lift_mov(ctx, ADD(R1V, SEXT16));
case V810_LDSR: return SETG(SR[I5], R2V);
case V810_STSR: return SETG(R2, VARG(SR[I5]));
case V810_NOT: return lift_op1(ctx, R1V, rz_il_op_new_log_not);
case V810_DIV:
case V810_DIVU: return lift_div(ctx, R2V, R1V);
case V810_OR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_or);
case V810_ORI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_or);
case V810_MUL: return lift_mul(ctx, R2V, R1V);
case V810_MULU: return lift_mulu(ctx, R2V, R1V);
case V810_XOR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_xor);
case V810_XORI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_xor);
case V810_AND: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_and);
case V810_ANDI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_and);
case V810_CMP: return lift_cmp(ctx, R2V, R1V, rz_il_op_new_sub);
case V810_CMP_IMM5: return lift_cmp(ctx, R2V, SEXT5, rz_il_op_new_sub);
case V810_SUB: return lift_op2(ctx, R2V, R1V, rz_il_op_new_sub);
case V810_ADD: return lift_op2(ctx, R2V, R1V, rz_il_op_new_add);
case V810_ADDI: return lift_op2(ctx, R1V, SEXT16, rz_il_op_new_add);
case V810_ADD_IMM5: return lift_op2(ctx, R2V, SEXT5, rz_il_op_new_add);
case V810_SHR: return lift_op2(ctx, R2V, R1V, shr0);
case V810_SHR_IMM5: return lift_op2(ctx, R2V, ZEXT5, shr0);
case V810_SAR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_shiftr_arith);
case V810_SAR_IMM5: return lift_op2(ctx, R2V, ZEXT5, rz_il_op_new_shiftr_arith);
case V810_SHL: return lift_op2(ctx, R2V, R1V, shl0);
case V810_SHL_IMM5: return lift_op2(ctx, R2V, ZEXT5, shl0);
case V810_INB:
case V810_LDB: return lift_ld(ctx, ADD(R1V, SEXT16), 8);
case V810_INH:
case V810_LDH: return lift_ld(ctx, ADD(R1V, SEXT16), 16);
case V810_INW:
case V810_LDW: return lift_ld(ctx, ADD(R1V, SEXT16), 32);
case V810_OUTB:
case V810_STB: return lift_st(ctx, ADD(R1V, SEXT16), 8);
case V810_OUTH:
case V810_STH: return lift_st(ctx, ADD(R1V, SEXT16), 16);
case V810_OUTW:
case V810_STW: return lift_st(ctx, ADD(R1V, SEXT16), 32);
case V810_HALT:
case V810_TRAP: return NOP();
case V810_RETI: return lift_reti(ctx);
case V810_JMP: return JMP(LOGAND(R1V, U32(0xfffffffe)));
case V810_JAL: return lift_jal(ctx);
case V810_JR: return lift_jr(ctx);
case V810_CLI:
case V810_SEI: return NOP();
case V810_CAXI: return lift_caxi(ctx);
case V810_EXT: {
switch (SUBOPC) {
case V810_EXT_CMPF_S: return lift_cmp(ctx, R2F, R1F, fsub_);
case V810_EXT_CVT_WS: return lift_fop1(ctx, R1V, bv2f32);
case V810_EXT_CVT_SW: return lift_op1(ctx, R1F, f32_2int);
case V810_EXT_ADDF_S: return lift_fop2(ctx, R2F, R1F, fadd_);
case V810_EXT_SUBF_S: return lift_fop2(ctx, R2F, R1F, fsub_);
case V810_EXT_MULF_S: return lift_fop2(ctx, R2F, R1F, fmul_);
case V810_EXT_DIVF_S: return lift_fop2(ctx, R2F, R1F, fdiv_);
case V810_EXT_XB:
case V810_EXT_XH:
case V810_EXT_REV: return NOP();
case V810_EXT_TRNC_SW: return lift_fop1(ctx, R1V, f32_trunc2int);
case V810_EXT_MPYHW: return NOP();
default: break;
}
break;
}
default:
if (COPCODE >> 3 == 4) {
RzILOpPure *cnd = NULL;
switch (CCOND) {
case C_BGT: cnd = INV(OR(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")), VARGb("PSW", "Z"))); break;
case C_BGE: cnd = INV(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV"))); break;
case C_BLT: cnd = XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")); break;
case C_BLE: cnd = OR(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")), VARGb("PSW", "Z")); break;
case C_BH: cnd = INV(OR(VARGb("PSW", "CY"), VARGb("PSW", "Z"))); break;
case C_BNL: cnd = INV(VARGb("PSW", "CY")); break;
case C_BL: cnd = VARGb("PSW", "CY"); break;
case C_BNH: cnd = OR(VARGb("PSW", "CY"), VARGb("PSW", "Z")); break;
case C_BE: cnd = VARGb("PSW", "Z"); break;
case C_BNE: cnd = INV(VARGb("PSW", "Z")); break;
case C_BV: cnd = VARGb("PSW", "OV"); break;
case C_BNV: cnd = INV(VARGb("PSW", "OV")); break;
case C_BN: cnd = VARGb("PSW", "S"); break;
case C_BP: cnd = INV(VARGb("PSW", "S")); break;
// case C_BC: break;
// case C_BNC: break;
// case C_BZ: break;
// case C_BNZ: break;
case C_BR: cnd = IL_TRUE; break;
case C_NOP: cnd = IL_FALSE; break;
default: break;
}
return lift_bcond(ctx, cnd);
}
break;
}
rz_warn_if_reached();
return NULL;
}
#include <rz_il/rz_il_opbuilder_end.h>
+1
View File
@@ -170,6 +170,7 @@ rz_analysis_sources = [
'arch/x86/x86_il.c',
'arch/8051/8051_il.c',
'arch/8051/8051_parse.c',
'arch/v810/v810_il.c',
'../asm/arch/amd29k/amd29k.c',
'../asm/arch/avr/disassembler.c',
'../asm/arch/cil/cil_dis.c',
+357 -238
View File
@@ -8,7 +8,7 @@
#include <rz_analysis.h>
#include <rz_util.h>
#include <v810_disas.h>
#include "../arch/v810/v810.h"
enum {
V810_FLAG_CY = 1,
@@ -17,41 +17,305 @@ enum {
V810_FLAG_Z = 8,
};
static void update_flags(RzAnalysisOp *op, int flags) {
static void update_flags(RzStrBuf *out, int flags) {
if (flags & V810_FLAG_CY) {
rz_strbuf_append(&op->esil, ",31,$c,cy,:=");
rz_strbuf_append(out, ",31,$c,cy,:=");
}
if (flags & V810_FLAG_OV) {
rz_strbuf_append(&op->esil, ",31,$o,ov,:=");
rz_strbuf_append(out, ",31,$o,ov,:=");
}
if (flags & V810_FLAG_S) {
rz_strbuf_append(&op->esil, ",31,$s,s,:=");
rz_strbuf_append(out, ",31,$s,s,:=");
}
if (flags & V810_FLAG_Z) {
rz_strbuf_append(&op->esil, ",$z,z,:=");
rz_strbuf_append(out, ",$z,z,:=");
}
}
static void clear_flags(RzAnalysisOp *op, int flags) {
static void clear_flags(RzStrBuf *out, int flags) {
if (flags & V810_FLAG_CY) {
rz_strbuf_append(&op->esil, ",0,cy,:=");
rz_strbuf_append(out, ",0,cy,:=");
}
if (flags & V810_FLAG_OV) {
rz_strbuf_append(&op->esil, ",0,ov,:=");
rz_strbuf_append(out, ",0,ov,:=");
}
if (flags & V810_FLAG_S) {
rz_strbuf_append(&op->esil, ",0,s,:=");
rz_strbuf_append(out, ",0,s,:=");
}
if (flags & V810_FLAG_Z) {
rz_strbuf_append(&op->esil, ",0,z,:=");
rz_strbuf_append(out, ",0,z,:=");
}
}
static void v810_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2) {
ut8 reg1 = 0, reg2 = 0, imm5 = 0, cond = 0;
switch (opcode) {
case V810_MOV:
rz_strbuf_appendf(out, "r%u,r%u,=",
REG1(word1), REG2(word1));
break;
case V810_MOV_IMM5:
rz_strbuf_appendf(out, "%d,r%u,=",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
break;
case V810_MOVHI:
rz_strbuf_appendf(out, "16,%hu,<<,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
break;
case V810_MOVEA:
rz_strbuf_appendf(out, "%hd,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
break;
case V810_LDSR:
case V810_STSR:
break;
case V810_NOT:
rz_strbuf_appendf(out, "r%u,0xffffffff,^,r%u,=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_DIV:
case V810_DIVU:
rz_strbuf_appendf(out, "r%u,r%u,/=,r%u,r%u,%%,r30,=",
REG1(word1), REG2(word1),
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
break;
case V810_JMP:
rz_strbuf_appendf(out, "r%u,pc,=",
REG1(word1));
break;
case V810_OR:
rz_strbuf_appendf(out, "r%u,r%u,|=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_ORI:
rz_strbuf_appendf(out, "%hu,r%u,|,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_MUL:
case V810_MULU:
rz_strbuf_appendf(out, "r%u,r%u,*=,32,r%u,r%u,*,>>,r30,=",
REG1(word1), REG2(word1),
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
break;
case V810_XOR:
rz_strbuf_appendf(out, "r%u,r%u,^=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_XORI:
rz_strbuf_appendf(out, "%hu,r%u,^,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_AND:
rz_strbuf_appendf(out, "r%u,r%u,&=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_ANDI:
rz_strbuf_appendf(out, "%hu,r%u,&,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV | V810_FLAG_S);
break;
case V810_CMP:
rz_strbuf_appendf(out, "r%u,r%u,==",
REG1(word1), REG2(word1));
update_flags(out, -1);
break;
case V810_CMP_IMM5:
rz_strbuf_appendf(out, "%d,r%u,==",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
update_flags(out, -1);
break;
case V810_SUB:
rz_strbuf_appendf(out, "r%u,r%u,-=",
REG1(word1), REG2(word1));
update_flags(out, -1);
break;
case V810_ADD:
rz_strbuf_appendf(out, "r%u,r%u,+=",
REG1(word1), REG2(word1));
update_flags(out, -1);
break;
case V810_ADDI:
rz_strbuf_appendf(out, "%hd,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(out, -1);
break;
case V810_ADD_IMM5:
rz_strbuf_appendf(out, "%d,r%u,+=",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
update_flags(out, -1);
break;
case V810_SHR:
rz_strbuf_appendf(out, "r%u,r%u,>>=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_SHR_IMM5:
rz_strbuf_appendf(out, "%u,r%u,>>=",
(ut8)IMM5(word1), REG2(word1));
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_SAR:
reg1 = REG1(word1);
reg2 = REG2(word1);
rz_strbuf_appendf(out, "31,r%u,>>,?{,r%u,32,-,r%u,1,<<,--,<<,}{,0,},r%u,r%u,>>,|,r%u,=",
reg2, reg1, reg1, reg1, reg2, reg2);
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_SAR_IMM5:
imm5 = IMM5(word1);
reg2 = REG2(word1);
rz_strbuf_appendf(out, "31,r%u,>>,?{,%u,32,-,%u,1,<<,--,<<,}{,0,},%u,r%u,>>,|,r%u,=",
reg2, (ut8)imm5, (ut8)imm5, (ut8)imm5, reg2, reg2);
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_SHL:
rz_strbuf_appendf(out, "r%u,r%u,<<=",
REG1(word1), REG2(word1));
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_SHL_IMM5:
rz_strbuf_appendf(out, "%u,r%u,<<=",
(ut8)IMM5(word1), REG2(word1));
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(out, V810_FLAG_OV);
break;
case V810_LDB:
rz_strbuf_appendf(out, "r%u,%hd,+,[1],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(out, ",DUP,0x80,&,?{,0xffffff00,|,}");
break;
case V810_LDH:
rz_strbuf_appendf(out, "r%u,%hd,+,0xfffffffe,&,[2],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(out, ",DUP,0x8000,&,?{,0xffffff00,|,}");
break;
case V810_LDW:
rz_strbuf_appendf(out, "r%u,%hd,+,0xfffffffc,&,[4],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(out, ",DUP,0x80000000,&,?{,0xffffff00,|,}");
break;
case V810_STB:
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,=[1]",
REG2(word1), REG1(word1), word2);
break;
case V810_STH:
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,0xfffffffe,&,=[2]",
REG2(word1), REG1(word1), word2);
break;
case V810_STW:
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,=[4]",
REG2(word1), REG1(word1), word2);
break;
case V810_INB:
case V810_INH:
case V810_INW:
case V810_OUTB:
case V810_OUTH:
case V810_OUTW:
break;
case V810_TRAP:
rz_strbuf_appendf(out, "%u,TRAP", IMM5(word1));
break;
case V810_RETI:
// rz_strbuf_appendf (out, "np,?{,fepc,fepsw,}{,eipc,eipsw,},psw,=,pc,=");
break;
case V810_JAL:
case V810_JR: {
st32 jumpdisp = DISP26(word1, word2);
if (opcode == V810_JAL) {
rz_strbuf_appendf(out, "$$,4,+,r31,=,");
}
rz_strbuf_appendf(out, "$$,%d,+,pc,=", jumpdisp);
break;
}
default: {
if (OPCODE(word1) >> 3 == 4) {
cond = COND(word1);
if (cond == V810_COND_NOP) {
break;
}
st32 jumpdisp = DISP9(word1);
switch (cond) {
case V810_COND_V:
rz_strbuf_appendf(out, "ov");
break;
case V810_COND_L:
rz_strbuf_appendf(out, "cy");
break;
case V810_COND_E:
rz_strbuf_appendf(out, "z");
break;
case V810_COND_NH:
rz_strbuf_appendf(out, "cy,z,|");
break;
case V810_COND_N:
rz_strbuf_appendf(out, "s");
break;
case V810_COND_NONE:
rz_strbuf_appendf(out, "1");
break;
case V810_COND_LT:
rz_strbuf_appendf(out, "s,ov,^");
break;
case V810_COND_LE:
rz_strbuf_appendf(out, "s,ov,^,z,|");
break;
case V810_COND_NV:
rz_strbuf_appendf(out, "ov,!");
break;
case V810_COND_NL:
rz_strbuf_appendf(out, "cy,!");
break;
case V810_COND_NE:
rz_strbuf_appendf(out, "z,!");
break;
case V810_COND_H:
rz_strbuf_appendf(out, "cy,z,|,!");
break;
case V810_COND_P:
rz_strbuf_appendf(out, "s,!");
break;
case V810_COND_GE:
rz_strbuf_appendf(out, "s,ov,^,!");
break;
case V810_COND_GT:
rz_strbuf_appendf(out, "s,ov,^,z,|,!");
break;
default: break;
}
rz_strbuf_appendf(out, ",?{,$$,%d,+,pc,=,}", jumpdisp);
}
break;
}
}
}
static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) {
int ret;
ut8 opcode, reg1, reg2, imm5, cond;
ut16 word1, word2 = 0;
st32 jumpdisp;
int ret = 0;
ut8 opcode = 0, cond = 0;
ut16 word1 = 0, word2 = 0;
st32 jumpdisp = 0;
struct v810_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
@@ -68,7 +332,6 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
}
op->addr = addr;
opcode = OPCODE(word1);
if (opcode >> 3 == 0x4) {
opcode &= 0x20;
@@ -76,219 +339,69 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
switch (opcode) {
case V810_MOV:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
rz_strbuf_appendf(&op->esil, "r%u,r%u,=",
REG1(word1), REG2(word1));
break;
case V810_MOV_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
rz_strbuf_appendf(&op->esil, "%d,r%u,=",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
break;
case V810_MOVHI:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
rz_strbuf_appendf(&op->esil, "16,%hu,<<,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
break;
case V810_MOVEA:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
rz_strbuf_appendf(&op->esil, "%hd,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
break;
case V810_LDSR:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
break;
case V810_STSR:
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
break;
case V810_NOT:
op->type = RZ_ANALYSIS_OP_TYPE_NOT;
rz_strbuf_appendf(&op->esil, "r%u,0xffffffff,^,r%u,=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_DIV:
case V810_DIVU:
op->type = RZ_ANALYSIS_OP_TYPE_DIV;
rz_strbuf_appendf(&op->esil, "r%u,r%u,/=,r%u,r%u,%%,r30,=",
REG1(word1), REG2(word1),
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
break;
case V810_JMP:
if (REG1(word1) == 31) {
op->type = RZ_ANALYSIS_OP_TYPE_RET;
} else {
op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
}
rz_strbuf_appendf(&op->esil, "r%u,pc,=",
REG1(word1));
break;
case V810_OR:
op->type = RZ_ANALYSIS_OP_TYPE_OR;
rz_strbuf_appendf(&op->esil, "r%u,r%u,|=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_ORI:
op->type = RZ_ANALYSIS_OP_TYPE_OR;
rz_strbuf_appendf(&op->esil, "%hu,r%u,|,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_MUL:
case V810_MULU:
op->type = RZ_ANALYSIS_OP_TYPE_MUL;
rz_strbuf_appendf(&op->esil, "r%u,r%u,*=,32,r%u,r%u,*,>>,r30,=",
REG1(word1), REG2(word1),
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
break;
case V810_XOR:
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
rz_strbuf_appendf(&op->esil, "r%u,r%u,^=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_XORI:
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
rz_strbuf_appendf(&op->esil, "%hu,r%u,^,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_AND:
op->type = RZ_ANALYSIS_OP_TYPE_AND;
rz_strbuf_appendf(&op->esil, "r%u,r%u,&=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_ANDI:
op->type = RZ_ANALYSIS_OP_TYPE_AND;
rz_strbuf_appendf(&op->esil, "%hu,r%u,&,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV | V810_FLAG_S);
break;
case V810_CMP:
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
rz_strbuf_appendf(&op->esil, "r%u,r%u,==",
REG1(word1), REG2(word1));
update_flags(op, -1);
break;
case V810_CMP_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
rz_strbuf_appendf(&op->esil, "%d,r%u,==",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
update_flags(op, -1);
break;
case V810_SUB:
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
rz_strbuf_appendf(&op->esil, "r%u,r%u,-=",
REG1(word1), REG2(word1));
update_flags(op, -1);
break;
case V810_ADD:
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
rz_strbuf_appendf(&op->esil, "r%u,r%u,+=",
REG1(word1), REG2(word1));
update_flags(op, -1);
break;
case V810_ADDI:
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
rz_strbuf_appendf(&op->esil, "%hd,r%u,+,r%u,=",
word2, REG1(word1), REG2(word1));
update_flags(op, -1);
break;
case V810_ADD_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
rz_strbuf_appendf(&op->esil, "%d,r%u,+=",
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
update_flags(op, -1);
break;
case V810_SHR:
op->type = RZ_ANALYSIS_OP_TYPE_SHR;
rz_strbuf_appendf(&op->esil, "r%u,r%u,>>=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_SHR_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_SHR;
rz_strbuf_appendf(&op->esil, "%u,r%u,>>=",
(ut8)IMM5(word1), REG2(word1));
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_SAR:
op->type = RZ_ANALYSIS_OP_TYPE_SAR;
reg1 = REG1(word1);
reg2 = REG2(word1);
rz_strbuf_appendf(&op->esil, "31,r%u,>>,?{,r%u,32,-,r%u,1,<<,--,<<,}{,0,},r%u,r%u,>>,|,r%u,=",
reg2, reg1, reg1, reg1, reg2, reg2);
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_SAR_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_SAR;
imm5 = IMM5(word1);
reg2 = REG2(word1);
rz_strbuf_appendf(&op->esil, "31,r%u,>>,?{,%u,32,-,%u,1,<<,--,<<,}{,0,},%u,r%u,>>,|,r%u,=",
reg2, (ut8)imm5, (ut8)imm5, (ut8)imm5, reg2, reg2);
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_SHL:
op->type = RZ_ANALYSIS_OP_TYPE_SHL;
rz_strbuf_appendf(&op->esil, "r%u,r%u,<<=",
REG1(word1), REG2(word1));
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_SHL_IMM5:
op->type = RZ_ANALYSIS_OP_TYPE_SHL;
rz_strbuf_appendf(&op->esil, "%u,r%u,<<=",
(ut8)IMM5(word1), REG2(word1));
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
clear_flags(op, V810_FLAG_OV);
break;
case V810_LDB:
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,[1],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(&op->esil, ",DUP,0x80,&,?{,0xffffff00,|,}");
break;
case V810_LDH:
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,0xfffffffe,&,[2],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(&op->esil, ",DUP,0x8000,&,?{,0xffffff00,|,}");
break;
case V810_LDW:
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,0xfffffffc,&,[4],r%u,=",
REG1(word1), word2, REG2(word1));
rz_strbuf_appendf(&op->esil, ",DUP,0x80000000,&,?{,0xffffff00,|,}");
break;
case V810_STB:
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,=[1]",
REG2(word1), REG1(word1), word2);
break;
case V810_STH:
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,0xfffffffe,&,=[2]",
REG2(word1), REG1(word1), word2);
break;
case V810_STW:
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,=[4]",
REG2(word1), REG1(word1), word2);
break;
case V810_INB:
case V810_INH:
@@ -300,11 +413,16 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
break;
case V810_TRAP:
op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
rz_strbuf_appendf(&op->esil, "%u,TRAP", IMM5(word1));
break;
case V810_RETI:
op->type = RZ_ANALYSIS_OP_TYPE_RET;
// rz_strbuf_appendf (&op->esil, "np,?{,fepc,fepsw,}{,eipc,eipsw,},psw,=,pc,=");
break;
case V810_JMP:
if (REG1(word1) == 31) {
op->type = RZ_ANALYSIS_OP_TYPE_RET;
} else {
op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
}
break;
case V810_JAL:
case V810_JR:
@@ -314,76 +432,44 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
if (opcode == V810_JAL) {
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
rz_strbuf_appendf(&op->esil, "$$,4,+,r31,=,");
} else {
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
}
rz_strbuf_appendf(&op->esil, "$$,%d,+,pc,=", jumpdisp);
break;
case V810_BCOND:
cond = COND(word1);
if (cond == V810_COND_NOP) {
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
break;
}
default:
if (OPCODE(word1) >> 3 == 4) {
cond = COND(word1);
if (cond == V810_COND_NOP) {
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
break;
}
jumpdisp = DISP9(word1);
op->jump = addr + jumpdisp;
op->fail = addr + 2;
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
switch (cond) {
case V810_COND_V:
rz_strbuf_appendf(&op->esil, "ov");
break;
case V810_COND_L:
rz_strbuf_appendf(&op->esil, "cy");
break;
case V810_COND_E:
rz_strbuf_appendf(&op->esil, "z");
break;
case V810_COND_NH:
rz_strbuf_appendf(&op->esil, "cy,z,|");
break;
case V810_COND_N:
rz_strbuf_appendf(&op->esil, "s");
break;
case V810_COND_NONE:
rz_strbuf_appendf(&op->esil, "1");
break;
case V810_COND_LT:
rz_strbuf_appendf(&op->esil, "s,ov,^");
break;
case V810_COND_LE:
rz_strbuf_appendf(&op->esil, "s,ov,^,z,|");
break;
case V810_COND_NV:
rz_strbuf_appendf(&op->esil, "ov,!");
break;
case V810_COND_NL:
rz_strbuf_appendf(&op->esil, "cy,!");
break;
case V810_COND_NE:
rz_strbuf_appendf(&op->esil, "z,!");
break;
case V810_COND_H:
rz_strbuf_appendf(&op->esil, "cy,z,|,!");
break;
case V810_COND_P:
rz_strbuf_appendf(&op->esil, "s,!");
break;
case V810_COND_GE:
rz_strbuf_appendf(&op->esil, "s,ov,^,!");
break;
case V810_COND_GT:
rz_strbuf_appendf(&op->esil, "s,ov,^,z,|,!");
break;
jumpdisp = DISP9(word1);
op->jump = addr + jumpdisp;
op->fail = addr + 2;
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
}
rz_strbuf_appendf(&op->esil, ",?{,$$,%d,+,pc,=,}", jumpdisp);
break;
}
if (mask & RZ_ANALYSIS_OP_MASK_DISASM) {
op->mnemonic = rz_str_newf("%s %s", cmd.instr, cmd.operands);
}
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
v810_esil(&op->esil, opcode, word1, word2);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
V810AnalysisContext ctx = { 0 };
ctx.a = analysis;
ctx.w1 = word1;
ctx.w2 = word2;
ctx.pc = addr;
op->il_op = v810_il_op(&ctx);
}
return ret;
}
@@ -431,15 +517,47 @@ static char *get_reg_profile(RzAnalysis *analysis) {
"gpr r31 .32 124 0\n"
"gpr pc .32 128 0\n"
"gpr psw .32 132 0\n"
"gpr np .1 132.16 0\n"
"gpr ep .1 132.17 0\n"
"gpr ae .1 132.18 0\n"
"gpr id .1 132.19 0\n"
"flg cy .1 132.28 0\n"
"flg ov .1 132.29 0\n"
"flg s .1 132.30 0\n"
"flg z .1 132.31 0\n";
"gpr EIPC .32 132 0\n"
"gpr EIPSW .32 136 0\n"
"gpr FEPC .32 140 0\n"
"gpr FEPSW .32 144 0\n"
"gpr ECR .32 148 0\n"
"gpr PSW .32 152 0\n"
"gpr PIR .32 156 0\n"
"gpr TKCW .32 160 0\n"
"gpr Reserved_8 .32 164 0\n"
"gpr Reserved_9 .32 168 0\n"
"gpr Reserved_10 .32 172 0\n"
"gpr Reserved_11 .32 176 0\n"
"gpr Reserved_12 .32 180 0\n"
"gpr Reserved_13 .32 184 0\n"
"gpr Reserved_14 .32 188 0\n"
"gpr Reserved_15 .32 192 0\n"
"gpr Reserved_16 .32 196 0\n"
"gpr Reserved_17 .32 200 0\n"
"gpr Reserved_18 .32 204 0\n"
"gpr Reserved_19 .32 208 0\n"
"gpr Reserved_20 .32 212 0\n"
"gpr Reserved_21 .32 216 0\n"
"gpr Reserved_22 .32 220 0\n"
"gpr Reserved_23 .32 224 0\n"
"gpr CHCW .32 228 0\n"
"gpr ADTRE .32 232 0\n"
"gpr Reserved_26 .32 236 0\n"
"gpr Reserved_27 .32 240 0\n"
"gpr Reserved_28 .32 244 0\n"
"gpr Reserved_29 .32 248 0\n"
"gpr Reserved_30 .32 252 0\n"
"gpr Reserved_31 .32 256 0\n"
"gpr np .1 152.16 0\n"
"gpr ep .1 152.17 0\n"
"gpr ae .1 152.18 0\n"
"gpr id .1 152.19 0\n"
"flg cy .1 152.28 0\n"
"flg ov .1 152.29 0\n"
"flg s .1 152.30 0\n"
"flg z .1 152.31 0\n";
return strdup(p);
}
@@ -452,6 +570,7 @@ RzAnalysisPlugin rz_analysis_plugin_v810 = {
.bits = 32,
.op = v810_op,
.esil = true,
.il_config = v810_il_config,
.get_reg_profile = get_reg_profile,
};
+1
View File
@@ -276,6 +276,7 @@ static const struct arch_translation arch_translation_table[] = {
{ EM_VIDEOCORE4, "vc4" },
{ EM_MSP430, "msp430" },
{ EM_SH, "sh" },
{ EM_V810, "v810" },
{ EM_V800, "v850" },
{ EM_V850, "v850" },
{ EM_IA_64, "ia64" },
+1
View File
@@ -374,6 +374,7 @@ typedef struct
chances of collision with official or non-GNU unofficial values. */
#define EM_ALPHA 0x9026
#define EM_V810 0x9081
/* Legal values for e_version (version). */
+32 -1
View File
@@ -38,6 +38,37 @@ r29 = 0x00000000
r30 = 0x00000000
r31 = 0x00000000
pc = 0x00000000
psw = 0x00000000
EIPC = 0x00000000
EIPSW = 0x00000000
FEPC = 0x00000000
FEPSW = 0x00000000
ECR = 0x00000000
PSW = 0x00000000
PIR = 0x00000000
TKCW = 0x00000000
Reserved_8 = 0x00000000
Reserved_9 = 0x00000000
Reserved_10 = 0x00000000
Reserved_11 = 0x00000000
Reserved_12 = 0x00000000
Reserved_13 = 0x00000000
Reserved_14 = 0x00000000
Reserved_15 = 0x00000000
Reserved_16 = 0x00000000
Reserved_17 = 0x00000000
Reserved_18 = 0x00000000
Reserved_19 = 0x00000000
Reserved_20 = 0x00000000
Reserved_21 = 0x00000000
Reserved_22 = 0x00000000
Reserved_23 = 0x00000000
CHCW = 0x00000000
ADTRE = 0x00000000
Reserved_26 = 0x00000000
Reserved_27 = 0x00000000
Reserved_28 = 0x00000000
Reserved_29 = 0x00000000
Reserved_30 = 0x00000000
Reserved_31 = 0x00000000
EOF
RUN
+57 -57
View File
@@ -1,57 +1,57 @@
d "mov r1, r2" 4100
d "add r1, r2" 4104
d "sub r1, r2" 4108
d "cmp r1, r2" 410c
d "shl r1, r2" 4110
d "shr r1, r2" 4114
d "jmp [r1]" 0118
d "sar r1, r2" 411c
d "mul r1, r2" 4120
d "div r1, r2" 4124
d "mulu r1, r2" 4128
d "divu r1, r2" 412c
d "or r1, r2" 4130
d "and r1, r2" 4134
d "not r1, r2" 413c
d "mov -1, r2" 5f40
d "add 1, r2" 4144
d "cmp 0, r2" 404c
d "shl 8, r2" 4850
d "shr 24, r2" 5854
d "sar 0, r2" 405c
d "cli " 0058
d "sei " 0078
d "trap 15" 0f60
d "reti " 0064
d "halt " 0068
d "ldsr FEPSW, r2" 4370
d "stsr TKCW, r2" 4774
d "stsr s8, r2" 4874
d "bv -8" f881
d "ble 8" 088e
d "movea 0xffff, r1, r2" 41a0ffff
d "addi -1, r1, r2" 41a4ffff
d "jr -8" ffabf8ff
d "jal 8" 00ac0800
d "ori 0xff, r1, r2" 41b0ff00
d "andi 0x0, r1, r2" 41b40000
d "xori 0x0, r1, r2" 41b80000
d "movhi 0x501, r1, r2" 41bc0105
d "ld.b 0[r1], r2" 41c00000
d "ld.h 32[r1], r2" 41c42000
d "ld.w -32[r1], r2" 41cce0ff
d "st.b r2, -32[r1]" 41d0e0ff
d "st.h r2, 32[r1]" 41d42000
d "st.w r2, 0[r1]" 41dc0000
d "in.b 123[r1], r2" 41e07b00
d "in.h 123[r1], r2" 41e47b00
d "caxi 123[r1], r2" 41e87b00
d "in.w 123[r1], r2" 41ec7b00
d "out.b r2, 123[r1]" 41f07b00
d "out.h r2, 123[r1]" 41f47b00
d "out.w r2, 123[r1]" 41fc7b00
d "mulf.s r11, r10" 4bf90018
d "cvt.sw r10, r11" 6af9000c
d "subf.s r15, r30" cffb0014
d "rev r15, r10" 4ff90028
d "xb r11" 60f90020
d "mov r1, r2" 4100 0x0 (set r2 (var r1))
d "add r1, r2" 4104 0x0 (seq (set result (+ (var r2) (var r1))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (var r2)) (! (== (var result) (var r2)))) (&& (sle (var result) (var r1)) (! (== (var result) (var r1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "sub r1, r2" 4108 0x0 (seq (set result (- (var r2) (var r1))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "cmp r1, r2" 410c 0x0 (seq (set result (- (var r2) (var r1))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "shl r1, r2" 4110 0x0 (seq (set result (<< (var r2) (var r1) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (>> (var r2) (- (bv 32 0x20) (var r1)) false)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "shr r1, r2" 4114 0x0 (seq (set result (>> (var r2) (var r1) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (bv 32 0x1) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "jmp [r1]" 0118 0x0 (jmp (& (var r1) (bv 32 0xfffffffe)))
d "sar r1, r2" 411c 0x0 (seq (set result (>> (var r2) (var r1) (msb (var r2)))) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (bv 32 0x1) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "mul r1, r2" 4120 0x0 (seq (set result (* (cast 64 (msb (var r2)) (var r2)) (cast 64 (msb (var r1)) (var r1)))) (set r2 (cast 32 false (var result))) (set r30 (cast 32 false (>> (var result) (bv 32 0x20) false))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "div r1, r2" 4124 0x0 (seq (set r2 (div (var r2) (var r1))) (set r30 (mod (var r2) (var r1))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "mulu r1, r2" 4128 0x0 (seq (set result (* (cast 64 false (var r2)) (cast 64 false (var r1)))) (set r2 (cast 32 false (var result))) (set r30 (cast 32 false (>> (var result) (bv 32 0x20) false))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "divu r1, r2" 412c 0x0 (seq (set r2 (div (var r2) (var r1))) (set r30 (mod (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "or r1, r2" 4130 0x0 (seq (set result (| (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "and r1, r2" 4134 0x0 (seq (set result (& (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "not r1, r2" 413c 0x0 (seq (set r2 (~ (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "mov -1, r2" 5f40 0x0 (set r2 (bv 32 0xffffffff))
d "add 1, r2" 4144 0x0 (seq (set result (+ (var r2) (bv 32 0x1))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (var r2)) (! (== (var result) (var r2)))) (&& (sle (var result) (bv 32 0x1)) (! (== (var result) (bv 32 0x1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "cmp 0, r2" 404c 0x0 (seq (set result (- (var r2) (bv 32 0x0))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "shl 8, r2" 4850 0x0 (seq (set result (<< (var r2) (bv 32 0x8) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x8))) (! (is_zero (>> (var r2) (- (bv 32 0x20) (bv 32 0x8)) false)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "shr 24, r2" 5854 0x0 (seq (set result (>> (var r2) (bv 32 0x18) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (var r24))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (var r24) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "sar 0, r2" 405c 0x0 (seq (set result (>> (var r2) (bv 32 0x0) (msb (var r2)))) (set PSW (| (| (<< (ite (&& (! (is_zero (var r0))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (var r0) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "cli" 0058 0x0 nop
d "sei" 0078 0x0 nop
d "trap 15" 0f60 0x0 nop
d "reti" 0064 0x0 (seq (set _pc (ite (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0xf) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (var FEPC) (var EIPC))) (set PSW (ite (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0xf) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (var FEPSW) (var EIPSW))) (jmp (var _pc)))
d "halt" 0068 0x0 nop
d "ldsr FEPSW, r2" 4370 0x0 (set FEPSW (var r2))
d "stsr TKCW, r2" 4774 0x0 (set r2 (var TKCW))
d "stsr s8, r2" 4874 0x0 (set r2 (var Reserved_8))
d "bv -8" f881 0x0 (branch (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x2) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (seq (set _pc (+ (bv 32 0x0) (bv 32 0xfffffff8))) (jmp (var _pc))) nop)
d "ble 8" 088e 0x0 (branch (|| (^^ (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x1) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x2) false) (bv 32 0x1))) (! (is_zero (var _v_part))))) (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x0) false) (bv 32 0x1))) (! (is_zero (var _v_part))))) (seq (set _pc (+ (bv 32 0x0) (bv 32 0x8))) (jmp (var _pc))) nop)
d "movea 0xffff, r1, r2" 41a0ffff 0x0 (set r2 (+ (var r1) (bv 32 0xffffffff)))
d "addi -1, r1, r2" 41a4ffff 0x0 (seq (set result (+ (var r1) (bv 32 0xffffffff))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (bv 32 0xffffffff)) (! (== (var result) (bv 32 0xffffffff)))) (&& (sle (var result) (var r1)) (! (== (var result) (var r1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "jr -8" ffabf8ff 0x0 (seq (set _pc (+ (bv 32 0x0) (bv 32 0xfffffff8))) (jmp (var _pc)))
d "jal 8" 00ac0800 0x0 (seq (set r31 (+ (bv 32 0x0) (bv 32 0x4))) (set _pc (+ (bv 32 0x0) (bv 32 0x8))) (jmp (var _pc)))
d "ori 0xff, r1, r2" 41b0ff00 0x0 (seq (set result (| (var r2) (bv 32 0xff))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "andi 0x0, r1, r2" 41b40000 0x0 (seq (set result (& (var r2) (bv 32 0x0))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "xori 0x0, r1, r2" 41b80000 0x0 (seq (set result (^ (var r2) (bv 32 0x0))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
d "movhi 0x501, r1, r2" 41bc0105 0x0 (set r2 (+ (var r1) (<< (bv 32 0x501) (bv 32 0x10) false)))
d "ld.b 0[r1], r2" 41c00000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x0))) (set r2 (let _v (cast 32 false (loadw 0 8 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x8)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)))))))
d "ld.h 32[r1], r2" 41c42000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x20))) (set r2 (let _v (cast 32 false (loadw 0 16 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x10)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)))))))
d "ld.w -32[r1], r2" 41cce0ff 0x0 (seq (set _adr (+ (var r1) (bv 32 0xffffffe0))) (set r2 (loadw 0 32 (var _adr))))
d "st.b r2, -32[r1]" 41d0e0ff 0x0 (seq (set _adr (+ (var r1) (bv 32 0xffffffe0))) (storew 0 (var _adr) (cast 8 false (var r2))))
d "st.h r2, 32[r1]" 41d42000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x20))) (storew 0 (var _adr) (cast 16 false (var r2))))
d "st.w r2, 0[r1]" 41dc0000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x0))) (storew 0 (var _adr) (var r2)))
d "in.b 123[r1], r2" 41e07b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (let _v (cast 32 false (loadw 0 8 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x8)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)))))))
d "in.h 123[r1], r2" 41e47b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (let _v (cast 32 false (loadw 0 16 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x10)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)))))))
d "caxi 123[r1], r2" 41e87b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set _tmp (loadw 0 32 (var _adr))) (set result (- (var r2) (var _tmp))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (branch (is_zero (var result)) (seq (storew 0 (var _adr) (var r30)) (set r2 (var _tmp))) (seq (storew 0 (var _adr) (var _tmp)) (set r2 (var _tmp)))))
d "in.w 123[r1], r2" 41ec7b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (loadw 0 32 (var _adr))))
d "out.b r2, 123[r1]" 41f07b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (cast 8 false (var r2))))
d "out.h r2, 123[r1]" 41f47b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (cast 16 false (var r2))))
d "out.w r2, 123[r1]" 41fc7b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (var r2)))
d "mulf.s r11, r10" 4bf90018 0x0 (seq (set result (*. rne (float 0 (var r10) ) (float 0 (var r11) ))) (set PSW (| (| (| (| (| (<< (ite (! (is_fpos (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (! (|| (is_nan (var result)) (is_nan (float 0 (bv 32 0x0) )))) (<. (var result) (float 0 (bv 32 0x0) ))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_fzero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false)) (<< (ite (|| (is_nan (var result)) (is_inf (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x9) false)) (<< (ite (is_fzero (float 0 (var r11) )) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x7) false))) (set r10 (fbits (var result))))
d "cvt.sw r10, r11" 6af9000c 0x0 (seq (set r11 (fcast_sint 32 rne (float 0 (var r10) ))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r11) (bv 32 0x0)) (! (== (var r11) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r11)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
d "subf.s r15, r30" cffb0014 0x0 (seq (set result (-. rne (float 0 (var r30) ) (float 0 (var r15) ))) (set PSW (| (| (| (| (| (<< (ite (! (is_fpos (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (! (|| (is_nan (var result)) (is_nan (float 0 (bv 32 0x0) )))) (<. (var result) (float 0 (bv 32 0x0) ))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_fzero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false)) (<< (ite (|| (is_nan (var result)) (is_inf (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x9) false)) (<< (ite (is_fzero (float 0 (var r15) )) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x7) false))) (set r30 (fbits (var result))))
d "rev r15, r10" 4ff90028 0x0 nop
d "xb r11" 60f90020 0x0 nop
+15
View File
@@ -0,0 +1,15 @@
NAME=Testing the decryption in emulateme
FILE=bins/v810/emulateme.v810
TIMEOUT=30
CMDS=<<EOF
aaa
e io.cache=1
s entry0
aezi
aezsu 0x00008156
ps @ obj._seckrit
EOF
EXPECT=<<EOF
Hello from RzIL!
EOF
RUN