mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 15:41:38 +00:00
Get rid of some %\d$ constructions in anal_8051.c for #3944
This commit is contained in:
parent
557d35f4cc
commit
3ae8b9813b
@ -1,5 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2013 - pancake */
|
||||
/* Copyright 2015 - dkreuter */
|
||||
/* radare - LGPL - Copyright 2013-2016 - pancake, dkreuter */
|
||||
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
@ -11,6 +10,8 @@
|
||||
|
||||
#define IRAM 0x10000
|
||||
|
||||
static bool i8051_is_init = false;
|
||||
|
||||
static ut8 bitindex[] = {
|
||||
// bit 'i' can be found in (ram[bitindex[i>>3]] >> (i&7)) & 1
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x00
|
||||
@ -19,6 +20,49 @@ static ut8 bitindex[] = {
|
||||
0x00, 0x00, 0xD0, 0x00, 0xE0, 0x00, 0xF0, 0x00 // 0xC0
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
ut8 offset; // offset into memory, where the value is held
|
||||
ut8 resetvalue; // value the register takes in case of a reset
|
||||
ut8 num_bytes; // no more than sizeof(ut64)
|
||||
ut8 banked : 1;
|
||||
ut8 isdptr : 1;
|
||||
} RI8015Reg;
|
||||
|
||||
static RI8015Reg registers[] = {
|
||||
// keep these sorted
|
||||
{"acc", 0xE0, 0x00, 1, 0},
|
||||
{"b", 0xF0, 0x00, 1, 0},
|
||||
{"dph", 0x83, 0x00, 1, 0},
|
||||
{"dpl", 0x82, 0x00, 1, 0},
|
||||
{"dptr", 0x00, 0x00, 2, 0, 1},
|
||||
{"ie", 0xA8, 0x00, 1, 0},
|
||||
{"ip", 0xB8, 0x00, 1, 0},
|
||||
{"p0", 0x80, 0xFF, 1, 0},
|
||||
{"p1", 0x90, 0xFF, 1, 0},
|
||||
{"p2", 0xA0, 0xFF, 1, 0},
|
||||
{"p3", 0xB0, 0xFF, 1, 0},
|
||||
{"pcon", 0x87, 0x00, 1, 0},
|
||||
{"psw", 0xD0, 0x00, 1, 0},
|
||||
{"r0", 0x00, 0x00, 1, 1},
|
||||
{"r1", 0x01, 0x00, 1, 1},
|
||||
{"r2", 0x02, 0x00, 1, 1},
|
||||
{"r3", 0x03, 0x00, 1, 1},
|
||||
{"r4", 0x04, 0x00, 1, 1},
|
||||
{"r5", 0x05, 0x00, 1, 1},
|
||||
{"r6", 0x06, 0x00, 1, 1},
|
||||
{"r7", 0x07, 0x00, 1, 1},
|
||||
{"sbuf", 0x99, 0x00, 1, 0},
|
||||
{"scon", 0x98, 0x00, 1, 0},
|
||||
{"sp", 0x81, 0x07, 1, 0},
|
||||
{"tcon", 0x88, 0x00, 1, 0},
|
||||
{"th0", 0x8C, 0x00, 1, 0},
|
||||
{"th1", 0x8D, 0x00, 1, 0},
|
||||
{"tl0", 0x8A, 0x00, 1, 0},
|
||||
{"tl1", 0x8B, 0x00, 1, 0},
|
||||
{"tmod", 0x89, 0x00, 1, 0}
|
||||
};
|
||||
|
||||
#define emit(frag) r_strbuf_appendf(&op->esil, frag)
|
||||
#define emitf(...) r_strbuf_appendf(&op->esil, __VA_ARGS__)
|
||||
|
||||
@ -36,6 +80,8 @@ static ut8 bitindex[] = {
|
||||
#define JMP(skipbytes) skipbytes",+,pc,+="
|
||||
#define CJMP(target, skipbytes) "?{," ESX_##target "" JMP(skipbytes) ",}"
|
||||
#define BIT_R "%2$d,%1$d,[1],>>,1,&,"
|
||||
#define F_BIT_R "%d,%d,[1],>>,1,&,"
|
||||
#define A_BIT_R a2, a1
|
||||
|
||||
#define IRAM_BASE "0x10000"
|
||||
#define XRAM_BASE "0x10100"
|
||||
@ -93,22 +139,26 @@ static ut8 bitindex[] = {
|
||||
#define OP_GROUP_UNARY_4(base, op) TEMPLATE_4(base, OP_GROUP_UNARY_4_FMT, A, op, XXX)
|
||||
#define OP_GROUP_UNARY_4_FMT(databyte, lhs, op, xxx) XI(lhs, op)
|
||||
|
||||
////////
|
||||
|
||||
static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const char *buf_asm) {
|
||||
r_strbuf_init (&op->esil);
|
||||
r_strbuf_set (&op->esil, "");
|
||||
|
||||
switch (buf[0]) {
|
||||
const ut32 a1 = bitindex[buf[1] >> 3];
|
||||
const ut32 a2 = buf[1] & 7;
|
||||
const ut32 a3 = buf[2];
|
||||
|
||||
switch (buf[0]) {
|
||||
// Irregulars sorted by lower nibble
|
||||
case 0x00: /* nop */ emit(","); break;
|
||||
case 0x10: /* jbc */
|
||||
k(BIT_R "&,?{,%2$d,1,<<,255,^,%1$d,&=[1],%3$hhd,3,+,pc,+=,}"); break;
|
||||
emitf(F_BIT_R "&,?{,%d,1,<<,255,^,%d,&=[1],%hhd,3,+,pc,+=,}", A_BIT_R, a2, a1, a3);
|
||||
break;
|
||||
case 0x20: /* jb */
|
||||
k(BIT_R "&,?{,%3$hhd,3,+,pc,+=,}"); break;
|
||||
emitf(F_BIT_R "&,?{,%hhd,3,+,pc,+=,}", A_BIT_R, a3);
|
||||
break;
|
||||
case 0x30: /* jnb */
|
||||
k(BIT_R "&,!,?{,%3$hhd,3,+,pc,+=,}"); break;
|
||||
emitf(F_BIT_R "&,!,?{,%hhd,3,+,pc,+=,}", A_BIT_R, a3);
|
||||
break;
|
||||
case 0x40: /* jc */ emitf("C,!,?{,%d,2,+,pc,+=,}", (st8)buf[1]); break;
|
||||
case 0x50: /* jnc */ emitf("C,""?{,%d,2,+,pc,+=,}", (st8)buf[1]); break;
|
||||
case 0x60: /* jz */ emitf("A,!,?{,%d,2,+,pc,+=,}", (st8)buf[1]); break;
|
||||
@ -120,24 +170,27 @@ static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const
|
||||
case 0xC0: /* push */ h(XR(IB1) PUSH1); break;
|
||||
case 0xD0: /* pop */ h(POP1 XW(IB1)); break;
|
||||
case 0xE0: /* movx */ /* TODO */ break;
|
||||
case 0xF0: /* movx */ /* TODO */ break;
|
||||
|
||||
case 0xF0: /* TODO: movx */
|
||||
break;
|
||||
case 0x11: case 0x31: case 0x51: case 0x71:
|
||||
case 0x91: case 0xB1: case 0xD1: case 0xF1:
|
||||
emit(CALL("2")); // fall through
|
||||
emit (CALL ("2"));
|
||||
/* fall through */
|
||||
case 0x01: case 0x21: case 0x41: case 0x61:
|
||||
case 0x81: case 0xA1: case 0xC1: case 0xE1:
|
||||
emitf("0x%x,pc,=", (addr & 0xF800) | ((((unsigned short)buf[0])<<3) & 0x0700) | buf[1]); break;
|
||||
|
||||
case 0x02: /* ljmp */ emitf( "%d,pc,=", (unsigned int)((buf[1]<<8)+buf[2])); break;
|
||||
case 0x12: /* lcall */ emitf(CALL("3")",%d,pc,=", (unsigned int)((buf[1]<<8)+buf[2])); break;
|
||||
case 0x22: /* ret */ emitf(POP2 "pc,="); break;
|
||||
emitf ("0x%x,pc,=", (addr & 0xF800) | ((((ut16)buf[0])<<3) & 0x0700) | buf[1]);
|
||||
break;
|
||||
case 0x02: /* ljmp */ emitf ( "%d,pc,=", (ut32)((buf[1] << 8) + buf[2])); break;
|
||||
case 0x12: /* lcall */ emitf (CALL ("3")",%d,pc,=", (ut32)((buf[1] << 8) + buf[2])); break;
|
||||
case 0x22: /* ret */ emitf (POP2 "pc,="); break;
|
||||
case 0x32: /* reti */ /* TODO */ break;
|
||||
case 0x72: /* orl */ /* TODO */ break;
|
||||
case 0x82: /* anl */ /* TODO */ break;
|
||||
case 0x92: /* mov */ /* TODO */ break;
|
||||
case 0xA2: /* mov */ /* TODO */ break;
|
||||
case 0xB2: /* cpl */ k("%2$d,1,<<,%1$d,^=[1]"); break;
|
||||
case 0xB2: /* cpl */
|
||||
emitf("%d,1,<<,%d,^=[1]", a2, a1);
|
||||
break;
|
||||
case 0xC2: /* clr */ /* TODO */ break;
|
||||
|
||||
case 0x03: /* rr */ emit("1,A,0x101,*,>>,A,="); break;
|
||||
@ -162,88 +215,90 @@ static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const
|
||||
h (XR(IB1) "C,+," XI(A, "+")) break;
|
||||
|
||||
case 0x36: case 0x37:
|
||||
j (XR(R0I) "C,+," XI(A, "+")) break;
|
||||
|
||||
j (XR(R0I) "C,+," XI(A, "+"));
|
||||
break;
|
||||
case 0x38: case 0x39:
|
||||
case 0x3A: case 0x3B:
|
||||
case 0x3C: case 0x3D:
|
||||
case 0x3E: case 0x3F:
|
||||
h (XR(R0) "C,+," XI(A, "+")) break;
|
||||
|
||||
OP_GROUP_INPLACE_LHS_4(0x40, A, "|")
|
||||
OP_GROUP_INPLACE_LHS_4(0x50, A, "&")
|
||||
OP_GROUP_INPLACE_LHS_4(0x60, A, "^")
|
||||
|
||||
h (XR(R0) "C,+," XI(A, "+"));
|
||||
break;
|
||||
OP_GROUP_INPLACE_LHS_4 (0x40, A, "|")
|
||||
OP_GROUP_INPLACE_LHS_4 (0x50, A, "&")
|
||||
OP_GROUP_INPLACE_LHS_4 (0x60, A, "^")
|
||||
case 0x74:
|
||||
h (XR(L1) XW(A)) break;
|
||||
h (XR(L1) XW(A));
|
||||
break;
|
||||
case 0x75:
|
||||
h (XR(L2) XW(IB1)) break;
|
||||
|
||||
h (XR(L2) XW(IB1));
|
||||
break;
|
||||
case 0x76: case 0x77:
|
||||
j (XR(L1) XW(R0I)) break;
|
||||
|
||||
j (XR(L1) XW(R0I));
|
||||
break;
|
||||
case 0x78: case 0x79:
|
||||
case 0x7A: case 0x7B:
|
||||
case 0x7C: case 0x7D:
|
||||
case 0x7E: case 0x7F:
|
||||
h (XR(L1) XW(R0)) break;
|
||||
|
||||
case 0x84:
|
||||
/* div */ emit("B,!,OV,=,0,A,B,A,/=,A,B,*,-,-,B,=,0,C,="); break;
|
||||
case 0x85:
|
||||
/* mov */ h(IRAM_BASE ",%2$d,+,[1]," IRAM_BASE ",%2$d,+,=[1]"); break;
|
||||
|
||||
h (XR(L1) XW(R0));
|
||||
break;
|
||||
case 0x84: /* div */
|
||||
emit("B,!,OV,=,0,A,B,A,/=,A,B,*,-,-,B,=,0,C,=");
|
||||
break;
|
||||
case 0x85: /* mov */
|
||||
h(IRAM_BASE ",%2$d,+,[1]," IRAM_BASE ",%2$d,+,=[1]");
|
||||
break;
|
||||
case 0x86: case 0x87:
|
||||
j (XR(R0I) XW(IB1)) break;
|
||||
|
||||
j (XR(R0I) XW(IB1));
|
||||
break;
|
||||
case 0x88: case 0x89:
|
||||
case 0x8A: case 0x8B:
|
||||
case 0x8C: case 0x8D:
|
||||
case 0x8E: case 0x8F:
|
||||
h (XR(R0) XW(IB1)) break;
|
||||
|
||||
h (XR(R0) XW(IB1));
|
||||
break;
|
||||
OP_GROUP_INPLACE_LHS_4(0x90, A, ".")
|
||||
|
||||
case 0xA4:
|
||||
/* mul */ emit("8,A,B,*,NUM,>>,NUM,!,!,OV,=,B,=,A,=,0,C,="); break;
|
||||
case 0xA5: /* ??? */ emit("0,TRAP"); break;
|
||||
case 0xA6: case 0xA7:
|
||||
j (XR(IB1) XW(R0I)) break;
|
||||
|
||||
j (XR(IB1) XW(R0I));
|
||||
break;
|
||||
case 0xA8: case 0xA9:
|
||||
case 0xAA: case 0xAB:
|
||||
case 0xAC: case 0xAD:
|
||||
case 0xAE: case 0xAF:
|
||||
h (XR(IB1) XW(R0)) break;
|
||||
|
||||
h (XR(IB1) XW(R0));
|
||||
break;
|
||||
case 0xB4:
|
||||
h (XR(L1) XR(A) "!=,?{,%3$hhd,2,+pc,+=,}") break;
|
||||
h (XR(L1) XR(A) "!=,?{,%3$hhd,2,+pc,+=,}");
|
||||
break;
|
||||
case 0xB5:
|
||||
h (XR(IB1) XR(A) "!=,?{,%3$hhd,2,+pc,+=,}") break;
|
||||
|
||||
h (XR(IB1) XR(A) "!=,?{,%3$hhd,2,+pc,+=,}");
|
||||
break;
|
||||
case 0xB6: case 0xB7:
|
||||
j (XR(L1) XR(R0I) "!=,?{,%3$hhd,2,+pc,+=,}") break;
|
||||
|
||||
j (XR(L1) XR(R0I) "!=,?{,%3$hhd,2,+pc,+=,}");
|
||||
break;
|
||||
case 0xB8: case 0xB9:
|
||||
case 0xBA: case 0xBB:
|
||||
case 0xBC: case 0xBD:
|
||||
case 0xBE: case 0xBF:
|
||||
h (XR(L1) XR(R0) "!=,?{,%3$hhd,2,+pc,+=,}") break;
|
||||
|
||||
case 0xC4:
|
||||
/* swap */ emit("4,A,0x101,*,>>,A,="); break;
|
||||
h (XR(L1) XR(R0) "!=,?{,%3$hhd,2,+pc,+=,}");
|
||||
break;
|
||||
case 0xC4: /* swap */
|
||||
emit("4,A,0x101,*,>>,A,=");
|
||||
break;
|
||||
case 0xC5:
|
||||
/* xch */ /* TODO */ break;
|
||||
|
||||
/* xch */ /* TODO */
|
||||
break;
|
||||
case 0xC6: case 0xC7:
|
||||
/* xch */ /* TODO */ break;
|
||||
|
||||
/* xch */ /* TODO */
|
||||
break;
|
||||
case 0xC8: case 0xC9:
|
||||
case 0xCA: case 0xCB:
|
||||
case 0xCC: case 0xCD:
|
||||
case 0xCE: case 0xCF:
|
||||
/* xch */ h (XR(A) XR(R0) XW(A) "," XW(R0)); break;
|
||||
|
||||
case 0xCE: case 0xCF: /* xch */
|
||||
h (XR(A) XR(R0) XW(A) "," XW(R0));
|
||||
break;
|
||||
case 0xD2:
|
||||
/* setb */ /* TODO */ break;
|
||||
case 0xD3:
|
||||
@ -282,7 +337,7 @@ static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const
|
||||
|
||||
case 0xF2: case 0xF3:
|
||||
/* movx */ j(XR(A) XRAM_BASE "r%0$d,+,=[1]");
|
||||
|
||||
break;
|
||||
case 0xF4:
|
||||
/* cpl */ h ("255" XI(A, "^")) break;
|
||||
case 0xF5:
|
||||
@ -301,67 +356,25 @@ static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const
|
||||
}
|
||||
}
|
||||
|
||||
static struct r_i8015_reg {
|
||||
const char *name;
|
||||
ut8 offset; // offset into memory, where the value is held
|
||||
ut8 resetvalue; // value the register takes in case of a reset
|
||||
ut8 num_bytes; // no more than sizeof(ut64)
|
||||
ut8 banked : 1;
|
||||
ut8 isdptr : 1;
|
||||
} registers[] = {
|
||||
// keep these sorted
|
||||
{"acc", 0xE0, 0x00, 1, 0},
|
||||
{"b", 0xF0, 0x00, 1, 0},
|
||||
{"dph", 0x83, 0x00, 1, 0},
|
||||
{"dpl", 0x82, 0x00, 1, 0},
|
||||
{"dptr", 0x00, 0x00, 2, 0, 1},
|
||||
{"ie", 0xA8, 0x00, 1, 0},
|
||||
{"ip", 0xB8, 0x00, 1, 0},
|
||||
{"p0", 0x80, 0xFF, 1, 0},
|
||||
{"p1", 0x90, 0xFF, 1, 0},
|
||||
{"p2", 0xA0, 0xFF, 1, 0},
|
||||
{"p3", 0xB0, 0xFF, 1, 0},
|
||||
{"pcon", 0x87, 0x00, 1, 0},
|
||||
{"psw", 0xD0, 0x00, 1, 0},
|
||||
{"r0", 0x00, 0x00, 1, 1},
|
||||
{"r1", 0x01, 0x00, 1, 1},
|
||||
{"r2", 0x02, 0x00, 1, 1},
|
||||
{"r3", 0x03, 0x00, 1, 1},
|
||||
{"r4", 0x04, 0x00, 1, 1},
|
||||
{"r5", 0x05, 0x00, 1, 1},
|
||||
{"r6", 0x06, 0x00, 1, 1},
|
||||
{"r7", 0x07, 0x00, 1, 1},
|
||||
{"sbuf", 0x99, 0x00, 1, 0},
|
||||
{"scon", 0x98, 0x00, 1, 0},
|
||||
{"sp", 0x81, 0x07, 1, 0},
|
||||
{"tcon", 0x88, 0x00, 1, 0},
|
||||
{"th0", 0x8C, 0x00, 1, 0},
|
||||
{"th1", 0x8D, 0x00, 1, 0},
|
||||
{"tl0", 0x8A, 0x00, 1, 0},
|
||||
{"tl1", 0x8B, 0x00, 1, 0},
|
||||
{"tmod", 0x89, 0x00, 1, 0}
|
||||
};
|
||||
|
||||
static int i8051_hook_reg_read(RAnalEsil *, const char *, ut64 *, int *);
|
||||
|
||||
static int i8051_reg_compare(const void *name, const void *reg) {
|
||||
return strcmp((const char*)name, ((struct r_i8015_reg*)reg)->name);
|
||||
return strcmp ((const char*)name, ((RI8015Reg*)reg)->name);
|
||||
}
|
||||
|
||||
static struct r_i8015_reg *i8051_reg_find(const char *name) {
|
||||
return (struct r_i8015_reg *) bsearch(
|
||||
name,
|
||||
registers,
|
||||
sizeof(registers)/sizeof(registers[0]),
|
||||
sizeof(registers[0]),
|
||||
static RI8015Reg *i8051_reg_find(const char *name) {
|
||||
return (RI8015Reg *) bsearch (
|
||||
name, registers,
|
||||
sizeof (registers) / sizeof (registers[0]),
|
||||
sizeof (registers[0]),
|
||||
i8051_reg_compare);
|
||||
}
|
||||
|
||||
static int i8051_reg_get_offset(RAnalEsil *esil, struct r_i8015_reg *ri) {
|
||||
static int i8051_reg_get_offset(RAnalEsil *esil, RI8015Reg *ri) {
|
||||
ut8 offset = ri->offset;
|
||||
if (ri->banked) {
|
||||
ut64 psw = 0LL;
|
||||
i8051_hook_reg_read(esil, "psw", &psw, NULL);
|
||||
i8051_hook_reg_read (esil, "psw", &psw, NULL);
|
||||
offset += psw & 0x18;
|
||||
}
|
||||
return offset;
|
||||
@ -381,14 +394,13 @@ struct r_i8051_user {
|
||||
static int i8051_hook_reg_read(RAnalEsil *esil, const char *name, ut64 *res, int *size) {
|
||||
int ret = 0;
|
||||
ut64 val = 0LL;
|
||||
struct r_i8015_reg *ri;
|
||||
RI8015Reg *ri;
|
||||
RAnalEsilCallbacks cbs = esil->cb;
|
||||
|
||||
if ((ri = i8051_reg_find (name))) {
|
||||
ut8 offset = i8051_reg_get_offset(esil, ri);
|
||||
ret = r_anal_esil_mem_read (esil, IRAM + offset, (ut8*)res, ri->num_bytes);
|
||||
}
|
||||
|
||||
esil->cb = ocbs;
|
||||
if (!ret && ocbs.hook_reg_read) {
|
||||
ret = ocbs.hook_reg_read (esil, name, res, NULL);
|
||||
@ -403,25 +415,20 @@ static int i8051_hook_reg_read(RAnalEsil *esil, const char *name, ut64 *res, int
|
||||
|
||||
static int i8051_hook_reg_write(RAnalEsil *esil, const char *name, ut64 val) {
|
||||
int ret = 0;
|
||||
struct r_i8015_reg *ri;
|
||||
RI8015Reg *ri;
|
||||
RAnalEsilCallbacks cbs = esil->cb;
|
||||
|
||||
if ((ri = i8051_reg_find (name))) {
|
||||
ut8 offset = i8051_reg_get_offset(esil, ri);
|
||||
ret = r_anal_esil_mem_write (esil, IRAM + offset, (ut8*)&val, ri->num_bytes);
|
||||
}
|
||||
|
||||
esil->cb = ocbs;
|
||||
if (!ret && ocbs.hook_reg_write) {
|
||||
ret = ocbs.hook_reg_write (esil, name, val);
|
||||
}
|
||||
esil->cb = cbs;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool i8051_is_init = false;
|
||||
|
||||
static int esil_i8051_init (RAnalEsil *esil) {
|
||||
if (esil->cb.user) {
|
||||
return true;
|
||||
@ -474,8 +481,11 @@ static int i8051_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len
|
||||
char buf_asm[64];
|
||||
op->delay = 0;
|
||||
r_8051_op o = r_8051_decode (buf, len);
|
||||
memset(buf_asm, 0, sizeof (buf_asm));
|
||||
if (!o.name) return 0; // invalid instruction
|
||||
memset (buf_asm, 0, sizeof (buf_asm));
|
||||
if (!o.name) {
|
||||
// invalid instruction
|
||||
return 0;
|
||||
}
|
||||
tmp = r_8051_disasm (o, addr, buf_asm, sizeof (buf_asm));
|
||||
if (tmp) {
|
||||
if (strlen (tmp) < sizeof (buf_asm)) {
|
||||
@ -493,49 +503,41 @@ static int i8051_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len
|
||||
op->ptr = 0;
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->stackptr = 1;
|
||||
} else
|
||||
if (!strncmp (buf_asm, "pop", 3)) {
|
||||
} else if (!strncmp (buf_asm, "pop", 3)) {
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
op->ptr = 0;
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->stackptr = -1;
|
||||
} else
|
||||
if (!strncmp (buf_asm, "ret", 3)) {
|
||||
} else if (!strncmp (buf_asm, "ret", 3)) {
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->stackop = R_ANAL_STACK_INC;
|
||||
op->stackptr = -2;
|
||||
} else
|
||||
if (!strncmp (buf_asm, "nop", 3)) {
|
||||
} else if (!strncmp (buf_asm, "nop", 3)) {
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
} else
|
||||
if (!strncmp (buf_asm, "inv", 3)) {
|
||||
} else if (!strncmp (buf_asm, "inv", 3)) {
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
} else
|
||||
if ((!strncmp (buf_asm, "inc", 3)) ||
|
||||
} else if ((!strncmp (buf_asm, "inc", 3)) ||
|
||||
(!strncmp (buf_asm, "add", 3))) {
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
} else
|
||||
if ((!strncmp (buf_asm, "dec", 3)) ||
|
||||
} else if ((!strncmp (buf_asm, "dec", 3)) ||
|
||||
(!strncmp (buf_asm, "sub", 3))) {
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
} else
|
||||
if (!strncmp (buf_asm, "mov", 3)) {
|
||||
} else if (!strncmp (buf_asm, "mov", 3)) {
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
} else
|
||||
if (*buf_asm && !strncmp (buf_asm+1, "call", 4)) {
|
||||
} else if (*buf_asm && !strncmp (buf_asm+1, "call", 4)) {
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = o.addr;
|
||||
op->fail = addr+o.length;
|
||||
} else
|
||||
/* CJNE, DJNZ, JC, JNC, JZ, JB, JNB, LJMP, SJMP */
|
||||
if (buf_asm[0]=='j' || (buf_asm[0] && buf_asm[1] == 'j'))
|
||||
{
|
||||
if (buf_asm[0]=='j' || (buf_asm[0] && buf_asm[1] == 'j')) {
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
if (o.operand == OFFSET)
|
||||
if (o.operand == OFFSET) {
|
||||
op->jump = o.addr+addr+o.length;
|
||||
else
|
||||
op->jump = o.addr;
|
||||
op->fail = addr+o.length;
|
||||
} else {
|
||||
op->jump = o.addr;
|
||||
op->fail = addr+o.length;
|
||||
}
|
||||
}
|
||||
if (anal->decode) {
|
||||
ut8 copy[3] = {0, 0, 0};
|
||||
@ -545,7 +547,7 @@ static int i8051_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len
|
||||
return op->size = o.length;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_8051 = {
|
||||
RAnalPlugin r_anal_plugin_8051 = {
|
||||
.name = "8051",
|
||||
.arch = "8051",
|
||||
.bits = 8|16,
|
||||
@ -558,7 +560,7 @@ struct r_anal_plugin_t r_anal_plugin_8051 = {
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_8051,
|
||||
.version = R2_VERSION
|
||||
|
@ -49,8 +49,11 @@ RS1 RS0 Working Register Bank and Address
|
||||
#define _OFFSET(x) OFFSET, ((x[1])), NULL, buf
|
||||
#define _DIRECT(x) DIRECT, (x[1]), NULL, x
|
||||
|
||||
static const char *arg[] = { "#immed", "#imm", "@r0", "@r1",
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
|
||||
static const char *arg[] = {
|
||||
"#immed", "#imm", "@r0", "@r1",
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"
|
||||
};
|
||||
|
||||
static const char *ops[] = {
|
||||
"inc", // 0. 04 : immed=a
|
||||
"dec", // 1. 14 : immed=a
|
||||
@ -76,9 +79,12 @@ static const char *ops[] = {
|
||||
|
||||
r_8051_op r_8051_decode(const ut8 *buf, int len) {
|
||||
ut8 op = buf[0];
|
||||
if (!op) return _{ "nop", 1, NONE, 0 };
|
||||
if ((op&0xf)==1)
|
||||
if (!op) {
|
||||
return _{ "nop", 1, NONE, 0 };
|
||||
}
|
||||
if ((op & 0xf) == 1) {
|
||||
return _{((op>>4)%2)? "acall": "ajmp", 2, _ADDR11(buf)};
|
||||
}
|
||||
switch (op) {
|
||||
case 0x10: return _{ "jbc bit,", 3, _ADDR16(buf) };
|
||||
case 0x20: return _{ "jb bit,", 3, _ADDR16(buf) };
|
||||
@ -167,18 +173,24 @@ r_8051_op r_8051_decode(const ut8 *buf, int len) {
|
||||
static char *strdup_filter (const char *str, const ut8 *buf) {
|
||||
char *o;
|
||||
int i, j, len;
|
||||
if (!str) return NULL;
|
||||
if (!str || !buf) {
|
||||
return NULL;
|
||||
}
|
||||
len = strlen (str);
|
||||
if ((len * 4) + 1 < len) return NULL;
|
||||
if ((len * 4) + 1 < len) {
|
||||
return NULL;
|
||||
}
|
||||
o = malloc (1 + (len * 4));
|
||||
if (!o) return NULL;
|
||||
if (!o) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = j = 0; i < len; i++) {
|
||||
if (str[i] == '$') {
|
||||
int n = str[i+1];
|
||||
if (n>='0' && n<='9') {
|
||||
if (n >= '0' && n <= '9') {
|
||||
n -= '0';
|
||||
i++;
|
||||
j += sprintf (o+j, "0x%02x", buf[n]);
|
||||
j += sprintf (o + j, "0x%02x", buf[n]);
|
||||
} else {
|
||||
eprintf ("strdup_filter: Internal bug\n");
|
||||
}
|
||||
@ -202,18 +214,21 @@ char *r_8051_disasm(r_8051_op op, ut32 addr, char *str, int len) {
|
||||
switch (op.operand) {
|
||||
case NONE: strncpy (out, op.name, len-1); break;
|
||||
case ARG:
|
||||
if (!strncmp (op.arg, "#imm", 4))
|
||||
snprintf (out, len, "%s 0x%x", op.name, op.buf[1]);
|
||||
else snprintf (out, len, "%s %s", op.name, op.arg);
|
||||
if (!strncmp (op.arg, "#imm", 4))
|
||||
snprintf (out, len, "%s 0x%x", op.name, op.buf[1]);
|
||||
else snprintf (out, len, "%s %s", op.name, op.arg);
|
||||
break;
|
||||
case ADDR11:
|
||||
case ADDR16:
|
||||
case DIRECT: snprintf (out, len, "%s 0x%02x", op.name, op.addr); break;
|
||||
case DIRECT:
|
||||
snprintf (out, len, "%s 0x%02x", op.name, op.addr);
|
||||
break;
|
||||
case OFFSET:
|
||||
snprintf (out, len, "%s 0x%02x", op.name, op.addr+addr+2); break;
|
||||
snprintf (out, len, "%s 0x%02x", op.name, op.addr + addr + 2);
|
||||
break;
|
||||
}
|
||||
if (*out == '+') {
|
||||
eof = strchr (out+1, ';');
|
||||
eof = strchr (out + 1, ';');
|
||||
if (eof) {
|
||||
*eof = 0;
|
||||
tmp = strdup_filter (out+1, (const ut8*)op.buf);
|
||||
@ -222,7 +237,9 @@ char *r_8051_disasm(r_8051_op op, ut32 addr, char *str, int len) {
|
||||
strcat (out, tmp);
|
||||
free (tmp);
|
||||
free (tmp2);
|
||||
} else eprintf ("do8051disasm: Internal bug\n");
|
||||
} else {
|
||||
eprintf ("do8051disasm: Internal bug\n");
|
||||
}
|
||||
} else {
|
||||
tmp = out;
|
||||
out = strdup_filter (out, (const ut8*)op.buf);
|
||||
@ -235,7 +252,7 @@ char *r_8051_disasm(r_8051_op op, ut32 addr, char *str, int len) {
|
||||
|
||||
int main() {
|
||||
char *str;
|
||||
ut8 buf[3] = {0xb3, 0x11, 0x22};
|
||||
ut8 buf[3] = { 0xb3, 0x11, 0x22 };
|
||||
r_8051_ op = r_8051_decode (buf, sizeof (buf));
|
||||
str = r_8051_disasm (op, 0, NULL, 0);
|
||||
eprintf ("%s\n", str);
|
||||
|
@ -8,11 +8,12 @@ R_API RAsmCode *r_asm_code_new(void) {
|
||||
}
|
||||
|
||||
R_API void* r_asm_code_free(RAsmCode *acode) {
|
||||
if (!acode) return NULL;
|
||||
free (acode->buf);
|
||||
free (acode->buf_hex);
|
||||
free (acode->buf_asm);
|
||||
free (acode);
|
||||
if (acode) {
|
||||
free (acode->buf);
|
||||
free (acode->buf_hex);
|
||||
free (acode->buf_asm);
|
||||
free (acode);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user