mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +00:00
Honor plugin name in rate matching for RArch.use ##arch
* Fixes amd29k regressions
This commit is contained in:
parent
7652642373
commit
539c5aee90
2
dist/docker/Makefile
vendored
2
dist/docker/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
ifeq ($(uname -m),arm64)
|
||||
ifeq ($(shell uname -m),arm64)
|
||||
ARCH=arm64
|
||||
else
|
||||
ARCH=amd64
|
||||
|
1
dist/plugins-cfg/plugins.def.cfg
vendored
1
dist/plugins-cfg/plugins.def.cfg
vendored
@ -10,7 +10,6 @@ anal.avr
|
||||
anal.lanai_gnu
|
||||
anal.bpf
|
||||
anal.lm32
|
||||
anal.i4004
|
||||
anal.bf
|
||||
anal.bpf_cs
|
||||
anal.chip8
|
||||
|
1
dist/plugins-cfg/plugins.mingw.cfg
vendored
1
dist/plugins-cfg/plugins.mingw.cfg
vendored
@ -5,7 +5,6 @@ anal.arc
|
||||
anal.arm_cs
|
||||
anal.arm_gnu
|
||||
anal.avr
|
||||
anal.i4004
|
||||
anal.bf
|
||||
anal.chip8
|
||||
anal.lanai_gnu
|
||||
|
1
dist/plugins-cfg/plugins.nocs.cfg
vendored
1
dist/plugins-cfg/plugins.nocs.cfg
vendored
@ -3,7 +3,6 @@ anal.arc
|
||||
anal.arm_gnu
|
||||
anal.arm_v35
|
||||
anal.avr
|
||||
anal.i4004
|
||||
anal.bf
|
||||
anal.chip8
|
||||
anal.cr16
|
||||
|
1
dist/plugins-cfg/plugins.nogpl.cfg
vendored
1
dist/plugins-cfg/plugins.nogpl.cfg
vendored
@ -23,7 +23,6 @@ anal.v850
|
||||
anal.ws
|
||||
anal.x86_cs
|
||||
anal.xcore_cs
|
||||
anal.i4004
|
||||
arch.null
|
||||
arch.i4004
|
||||
esil.dummy
|
||||
|
1
dist/plugins-cfg/plugins.static.cfg
vendored
1
dist/plugins-cfg/plugins.static.cfg
vendored
@ -4,7 +4,6 @@ STATIC="anal.8051
|
||||
anal.arc
|
||||
anal.arm_cs
|
||||
anal.arm_gnu
|
||||
anal.i4004
|
||||
anal.bf
|
||||
anal.chip8
|
||||
anal.cris
|
||||
|
1
dist/plugins-cfg/plugins.static.nogpl.cfg
vendored
1
dist/plugins-cfg/plugins.static.nogpl.cfg
vendored
@ -1,7 +1,6 @@
|
||||
STATIC="anal.8051
|
||||
anal.arc
|
||||
anal.arm_cs
|
||||
anal.i4004
|
||||
anal.bf
|
||||
anal.chip8
|
||||
anal.cris
|
||||
|
1
dist/plugins-cfg/plugins.termux.cfg
vendored
1
dist/plugins-cfg/plugins.termux.cfg
vendored
@ -34,7 +34,6 @@ anal.pic
|
||||
anal.rsp
|
||||
anal.wasm
|
||||
anal.pyc
|
||||
anal.i4004
|
||||
arch.null
|
||||
arch.i4004
|
||||
esil.dummy
|
||||
|
@ -23,6 +23,7 @@ R_API void r_anal_set_limits(RAnal *anal, ut64 from, ut64 to) {
|
||||
}
|
||||
|
||||
R_API void r_anal_unset_limits(RAnal *anal) {
|
||||
r_return_if_fail (anal);
|
||||
R_FREE (anal->limit);
|
||||
}
|
||||
|
||||
@ -231,9 +232,10 @@ R_API char *r_anal_mnemonics(RAnal *anal, int id, bool json) {
|
||||
R_API bool r_anal_use(RAnal *anal, const char *name) {
|
||||
r_return_val_if_fail (anal, false);
|
||||
if (anal->arch) {
|
||||
bool res = r_arch_use (anal->arch, anal->config);
|
||||
bool res = r_arch_use (anal->arch, anal->config, name);
|
||||
if (res) {
|
||||
R_LOG_DEBUG ("sing experimental '%s' r_arch plugin", name);
|
||||
return true;
|
||||
} else {
|
||||
anal->arch->current = NULL;
|
||||
}
|
||||
@ -456,13 +458,20 @@ R_API void r_anal_purge(RAnal *anal) {
|
||||
r_anal_purge_imports (anal);
|
||||
}
|
||||
|
||||
R_API int r_anal_archinfo(RAnal *anal, int query) {
|
||||
// XXX deprecate
|
||||
R_API R_DEPRECATE int r_anal_archinfo(RAnal *anal, int query) {
|
||||
r_return_val_if_fail (anal, -1);
|
||||
switch (query) {
|
||||
case R_ANAL_ARCHINFO_MIN_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_MAX_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_INV_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_ALIGN:
|
||||
{
|
||||
int res = r_arch_info (anal->arch, NULL, query);
|
||||
if (res != -1) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (anal->cur && anal->cur->archinfo) {
|
||||
return anal->cur->archinfo (anal, query);
|
||||
}
|
||||
@ -713,8 +722,8 @@ R_API void r_anal_bind(RAnal *anal, RAnalBind *b) {
|
||||
b->anal = anal;
|
||||
b->get_fcn_in = r_anal_get_fcn_in;
|
||||
b->get_hint = r_anal_hint_get;
|
||||
b->encode = (RAnalEncode)r_anal_opasm;
|
||||
b->decode = (RAnalDecode)r_anal_op;
|
||||
b->encode = (RAnalEncode)r_anal_opasm; // TODO rename to encode
|
||||
b->decode = (RAnalDecode)r_anal_op; // TODO rename to decode
|
||||
b->opinit = r_anal_op_init;
|
||||
b->mnemonics = r_anal_mnemonics;
|
||||
b->opfini = r_anal_op_fini;
|
||||
|
@ -77,7 +77,6 @@ r_anal_sources = [
|
||||
'p/anal_evm_cs.c',
|
||||
'p/anal_gb.c',
|
||||
'p/anal_h8300.c',
|
||||
'p/anal_i4004.c',
|
||||
'p/anal_i8080.c',
|
||||
'p/anal_java.c',
|
||||
'p/anal_kvx.c',
|
||||
|
@ -90,14 +90,34 @@ static int defaultCycles(RAnalOp *op) {
|
||||
}
|
||||
|
||||
R_API int r_anal_opasm(RAnal *anal, ut64 addr, const char *s, ut8 *outbuf, int outlen) {
|
||||
if (anal && outbuf && outlen > 0 && anal->cur && anal->cur->opasm) {
|
||||
int ret = 0;
|
||||
if (outlen > 0 && anal->arch->current) {
|
||||
ret = r_arch_encode (anal->arch, addr, s, outbuf, outlen);
|
||||
// r_arch_op_to_analop (op, &archop);
|
||||
// ret = anal->arch->op (anal, op, addr, data, len, mask);
|
||||
if (ret < 1) {
|
||||
ret = r_arch_info (anal->arch, NULL, R_ANAL_ARCHINFO_INV_OP_SIZE);
|
||||
if (ret < 0) {
|
||||
ret = r_arch_info (anal->arch, NULL, R_ANAL_ARCHINFO_ALIGN);
|
||||
if (ret < 0) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// op->addr = addr;
|
||||
/* consider at least 1 byte to be part of the opcode */
|
||||
#if 0
|
||||
if (op->nopcode < 1) {
|
||||
op->nopcode = 1;
|
||||
}
|
||||
#endif
|
||||
} else if (anal && outbuf && outlen > 0 && anal->cur && anal->cur->opasm) {
|
||||
// use core binding to set asm.bits correctly based on the addr
|
||||
// this is because of the hassle of arm/thumb
|
||||
int ret = anal->cur->opasm (anal, addr, s, outbuf, outlen);
|
||||
ret = anal->cur->opasm (anal, addr, s, outbuf, outlen);
|
||||
/* consider at least 1 byte to be part of the opcode */
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
|
||||
|
@ -1,405 +0,0 @@
|
||||
/* radare - LGPL - Copyright 2016-2022 - pancake, condret */
|
||||
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
#include "../arch/i4004/i4004.c"
|
||||
|
||||
static bool set_reg_profile(RAnal *anal) {
|
||||
const char *p =
|
||||
"=PC PC\n"
|
||||
/* syntax not yet supported */
|
||||
// "=SP &PC1\n"
|
||||
"=A0 r0\n"
|
||||
"=A1 r1\n"
|
||||
"=A2 r2\n"
|
||||
"=A3 r3\n"
|
||||
"=R0 r0\n"
|
||||
"gpr r0 .4 0 0\n"
|
||||
"gpr r1 .4 .4 0\n"
|
||||
"gpr r0r1 1 0 0\n"
|
||||
"gpr r2 .4 .8 0\n"
|
||||
"gpr r3 .4 .12 0\n"
|
||||
"gpr r2r3 1 1 0\n"
|
||||
"gpr r4 .4 .16 0\n"
|
||||
"gpr r5 .4 .20 0\n"
|
||||
"gpr r4r5 1 2 0\n"
|
||||
"gpr r6 .4 .24 0\n"
|
||||
"gpr r7 .4 .28 0\n"
|
||||
"gpr r6r7 1 3 0\n"
|
||||
"gpr r8 .4 .32 0\n"
|
||||
"gpr r9 .4 .36 0\n"
|
||||
"gpr r8r9 1 4 0\n"
|
||||
"gpr r10 .4 .40 0\n"
|
||||
"gpr r11 .4 .44 0\n"
|
||||
"gpr r10r11 1 5 0\n"
|
||||
"gpr r12 .4 .52 0\n"
|
||||
"gpr r13 .4 .56 0\n"
|
||||
"gpr r12r13 1 6 0\n"
|
||||
"gpr r14 .4 .60 0\n"
|
||||
"gpr r15 .4 .64 0\n"
|
||||
"gpr r14r15 1 7 0\n"
|
||||
"gpr PC .12 .72 0\n"
|
||||
/* stack */
|
||||
"gpr PC1 .12 .88 0\n"
|
||||
"gpr PC2 .12 .104 0\n"
|
||||
"gpr PC3 .12 .120 0\n"
|
||||
;
|
||||
|
||||
return r_reg_set_profile_string (anal->reg, p);
|
||||
}
|
||||
|
||||
/* That 3 is a hack */
|
||||
static const int i4004_ins_len[16] = {
|
||||
1, 2, 3, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
static const char *i4004_e[16] = {
|
||||
"wrm",
|
||||
"wmp",
|
||||
"wrr",
|
||||
"wpm",
|
||||
"wr0",
|
||||
"wr1",
|
||||
"wr2",
|
||||
"wr3",
|
||||
"sbm",
|
||||
"rdm",
|
||||
"rdr",
|
||||
"adm",
|
||||
"rd0",
|
||||
"rd1",
|
||||
"rd2",
|
||||
"rd3"
|
||||
};
|
||||
|
||||
static const char *i4004_f[16] = {
|
||||
"clb",
|
||||
"clc",
|
||||
"iac",
|
||||
"cmc",
|
||||
"cma",
|
||||
"ral",
|
||||
"rar",
|
||||
"tcc",
|
||||
"dac", // decrement
|
||||
"tcs",
|
||||
"stc",
|
||||
"daa",
|
||||
"kbp",
|
||||
"dcl",
|
||||
"invalid",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
static int i4004_get_ins_len(ut8 hex) {
|
||||
ut8 high = (hex & 0xf0)>>4;
|
||||
int ret = i4004_ins_len[high];
|
||||
if (ret == 3) {
|
||||
ret = (hex & 1) ? 1 : 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i4004_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
|
||||
char basm[64];
|
||||
const size_t basz = sizeof (basm);
|
||||
int rlen = i4004_get_ins_len (*buf);
|
||||
if (!op) {
|
||||
return 2;
|
||||
}
|
||||
ut8 high = (*buf & 0xf0)>>4;
|
||||
ut8 low = (*buf & 0xf);
|
||||
basm[0] = 0;
|
||||
|
||||
if (rlen > len) {
|
||||
return op->size = 0;
|
||||
}
|
||||
switch (high) {
|
||||
case 0:
|
||||
if (low) {
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
strcpy (basm, "invalid");
|
||||
}
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
strcpy (basm, "nop");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "jcn 0x%x 0x%x", low, buf[1]);
|
||||
}
|
||||
op->jump = (addr & (~0xFF)) + buf[1];
|
||||
op->fail = addr + rlen;
|
||||
break;
|
||||
case 2:
|
||||
if (rlen == 1) {
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "src r%d", (low & 0xe) >> 1);
|
||||
}
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
op->val = buf[1];
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "fim r%dr%d, 0x%x", low & 0xe,
|
||||
(low & 0xe) + 1, buf[1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (low & 1) {
|
||||
op->type = R_ANAL_OP_TYPE_RJMP;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "jin r%dr%d", low & 0xe, (low & 0xe) + 1);
|
||||
}
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "fin r%dr%d", low & 0xe, (low & 0xe) + 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = (ut16) (low<<8) | buf[1];
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "jun 0x%x", (ut16)op->jump);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = (ut16) (low<<8) | buf[1];
|
||||
op->fail = addr + rlen;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "jms 0x%x", (ut16)op->jump);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "inc r%d", low);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->fail = (addr & (~0xFF)) + buf[1];
|
||||
op->jump = addr + rlen;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "isz r%d, 0x%x", low, buf[1]);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "add r%d", low);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "sub r%d", low);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "ld r%d", low);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
op->type = R_ANAL_OP_TYPE_XCHG;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "xch r%d", low);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "bbl 0x%x", low);
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
snprintf (basm, basz, "ldm 0x%x", low);
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
strncpy (basm, i4004_e[low], basz);
|
||||
basm[basz - 1] = '\0';
|
||||
break;
|
||||
case 15:
|
||||
strncpy (basm, i4004_f[low], basz);
|
||||
basm[basz - 1] = '\0';
|
||||
if (!strcmp (basm, "dac")) {
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!strcmp (basm, "invalid")) {
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
} else if (!strcmp (basm, "ral")) {
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
} else if (!strcmp (basm, "rar")) {
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
}
|
||||
if (mask & R_ARCH_OP_MASK_DISASM) {
|
||||
op->mnemonic = strdup (basm);
|
||||
}
|
||||
return op->size = rlen;
|
||||
}
|
||||
|
||||
static int i4004_anal_opasm(RAnal *a, ut64 addr, const char *str, ut8 *outbuf, int outsize) {
|
||||
char *s = strdup (str);
|
||||
r_str_case (s, false);
|
||||
s = r_str_replace (s, "_", "?", false); // mitigate a bug in sdb -C
|
||||
s = r_str_replace (s, ",", " _ ", false);
|
||||
int i, nelems;
|
||||
char **elems = r_str_argv (s, &nelems);
|
||||
RStrBuf *sbuf = r_strbuf_new (elems[0]);
|
||||
for (i = 1; i < nelems; i++) {
|
||||
if (r_is_valid_input_num_value (NULL, elems[i])) {
|
||||
r_strbuf_appendf (sbuf, " 0x%"PFMT64x, r_num_get (NULL, elems[i]));
|
||||
} else {
|
||||
r_strbuf_appendf (sbuf, " %s", elems[i]);
|
||||
}
|
||||
}
|
||||
Sdb *asm_db = sdb_new0 ();
|
||||
sdb_open_gperf (asm_db, (SdbGperf *)&gperf_i4004);
|
||||
char *hex_output = sdb_get (asm_db, r_strbuf_get (sbuf), NULL);
|
||||
sdb_free (asm_db);
|
||||
r_strbuf_free (sbuf);
|
||||
if (hex_output) {
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
r_hex_str2bin (hex_output, outbuf);
|
||||
free (hex_output);
|
||||
return 1;
|
||||
}
|
||||
if (strlen (elems[0]) != 3) {
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
return 0;
|
||||
}
|
||||
int ret = 0;
|
||||
switch (elems[0][0] << 16 | elems[0][1] << 8 | elems[0][2]) {
|
||||
case 0x6a636e: //jcn
|
||||
if (nelems > 2 && r_is_valid_input_num_value (NULL, elems[1])
|
||||
&& r_is_valid_input_num_value (NULL, elems[2])) {
|
||||
ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x10) {
|
||||
outbuf[0] = 0x10 | (ut8)v;
|
||||
v = r_num_get (NULL, elems[2]);
|
||||
if (v < 0x100) {
|
||||
outbuf[1] = (ut8)v;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x66696d: //fim
|
||||
if (nelems > 3 && !strcmp (elems[2], "_") && r_is_valid_input_num_value (NULL, elems[3])) {
|
||||
const ut64 v = r_num_get (NULL, elems[3]);
|
||||
if (v < 0x100) {
|
||||
ret = 2;
|
||||
if (!strcmp (elems[1], "r0r1")) {
|
||||
outbuf[0] = 0x20;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r2r3")) {
|
||||
outbuf[0] = 0x22;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r4r5")) {
|
||||
outbuf[0] = 0x24;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r6r7")) {
|
||||
outbuf[0] = 0x26;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r8r9")) {
|
||||
outbuf[0] = 0x28;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r10r11")) {
|
||||
outbuf[0] = 0x2a;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r12r14")) {
|
||||
outbuf[0] = 0x2c;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r14r15")) {
|
||||
outbuf[0] = 0x2e;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x6a756e: //jun
|
||||
if (nelems > 1 && r_is_valid_input_num_value (NULL, elems[1])) {
|
||||
const ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x1000) {
|
||||
outbuf[0] = 0x40 | (v & 0xf00) >> 8;
|
||||
outbuf[1] = v & 0xff;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x6a6d73: //jms
|
||||
if (nelems > 1 && r_is_valid_input_num_value (NULL, elems[1])) {
|
||||
const ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x1000) {
|
||||
outbuf[0] = 0x50 | (v & 0xf00) >> 8;
|
||||
outbuf[1] = v & 0xff;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x69737a: //isz
|
||||
if (nelems > 3 && elems[1][0] == 'r' && r_is_valid_input_num_value (NULL, &elems[1][1])
|
||||
&& !strcmp (elems[2], "_") && r_is_valid_input_num_value (NULL, elems[3])) {
|
||||
ut64 v = r_num_get (NULL, &elems[1][1]);
|
||||
if (v < 0x10) {
|
||||
outbuf[0] = 0x70 | (ut8)v;
|
||||
v = r_num_get (NULL, elems[3]);
|
||||
if (v < 0x100) {
|
||||
outbuf[1] = (ut8)v;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RAnalPlugin r_anal_plugin_i4004 = {
|
||||
.name = "i4004",
|
||||
.desc = "i4004 code analysis plugin",
|
||||
.license = "LGPL3",
|
||||
.arch = "i4004",
|
||||
.esil = false,
|
||||
.bits = 4,
|
||||
.author = "pancake, condret",
|
||||
.op = &i4004_op,
|
||||
.opasm = &i4004_anal_opasm,
|
||||
.set_reg_profile = &set_reg_profile
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
R_API RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_i4004,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
@ -1,9 +0,0 @@
|
||||
OBJ_I4004=anal_i4004.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_I4004}
|
||||
TARGET_I4004=anal_i4004.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_I4004}
|
||||
|
||||
${TARGET_I4004}: ${OBJ_I4004}
|
||||
${CC} $(call libname,anal_i4004) ${CFLAGS} -o anal_i4004.${EXT_SO} ${OBJ_I4004}
|
@ -11,6 +11,8 @@ pre: libr_arch.$(EXT_SO) libr_arch.$(EXT_AR)
|
||||
|
||||
include $(STATIC_ARCH_PLUGINS)
|
||||
STATIC_OBJS=$(subst ..,p/..,$(subst arch_,p/arch_,$(STATIC_OBJ)))
|
||||
OBJS=arch.o aconfig.o decoder.o switchop.o archop.o archvalue.o archcond.o ${STATIC_OBJS}
|
||||
OBJS=arch.o aconfig.o switchop.o archop.o archvalue.o archcond.o
|
||||
OBJS+=${STATIC_OBJS}
|
||||
OBJS+=encoder.o decoder.o
|
||||
|
||||
include ../rules.mk
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
static const RArchPlugin * const arch_static_plugins[] = { R_ARCH_STATIC_PLUGINS };
|
||||
|
||||
static void plugin_free (void *p) {
|
||||
static void plugin_free(void *p) {
|
||||
}
|
||||
|
||||
static void _decoder_free_cb (HtPPKv *kv) {
|
||||
static void _decoder_free_cb(HtPPKv *kv) {
|
||||
free (kv->key);
|
||||
RArchDecoder *decoder = (RArchDecoder *)kv->value;
|
||||
if (decoder->p->fini) {
|
||||
@ -40,7 +40,7 @@ R_API RArch *r_arch_new(void) {
|
||||
return a;
|
||||
}
|
||||
|
||||
static ut32 _rate_compat(RArchPlugin *p, RArchConfig *cfg) {
|
||||
static ut32 _rate_compat(RArchPlugin *p, RArchConfig *cfg, const char *name) {
|
||||
ut32 bits;
|
||||
switch (cfg->bits) {
|
||||
case 64:
|
||||
@ -69,8 +69,11 @@ static ut32 _rate_compat(RArchPlugin *p, RArchConfig *cfg) {
|
||||
break;
|
||||
}
|
||||
ut32 score = 0;
|
||||
if (name && !strcmp (p->name, name)) {
|
||||
score += 50;
|
||||
}
|
||||
if (!strcmp (p->arch, cfg->arch)) {
|
||||
score = 50;
|
||||
score += 50;
|
||||
}
|
||||
if (p->bits & bits) {
|
||||
score += (!!score) * 30;
|
||||
@ -81,27 +84,27 @@ static ut32 _rate_compat(RArchPlugin *p, RArchConfig *cfg) {
|
||||
return score;
|
||||
}
|
||||
|
||||
static char *_find_bestmatch(RList *plugins, RArchConfig *cfg) {
|
||||
static char *_find_bestmatch(RList *plugins, RArchConfig *cfg, const char *name) {
|
||||
ut8 best_score = 0;
|
||||
char *name = NULL;
|
||||
char *rname = NULL;
|
||||
RListIter *iter;
|
||||
RArchPlugin *p;
|
||||
r_list_foreach (plugins, iter, p) {
|
||||
const ut32 score = _rate_compat (p, cfg);
|
||||
const ut32 score = _rate_compat (p, cfg, name);
|
||||
if (score > best_score) {
|
||||
best_score = score;
|
||||
name = p->name;
|
||||
rname = p->name;
|
||||
}
|
||||
if (score == 100) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
return rname;
|
||||
}
|
||||
|
||||
// use config as new arch config and use matching decoder as current
|
||||
// must return arch->current, and remove that field. and use refcounting
|
||||
R_API bool r_arch_use(RArch *arch, RArchConfig *config) {
|
||||
R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name) {
|
||||
r_return_val_if_fail (arch, false);
|
||||
if (!config) {
|
||||
config = arch->cfg;
|
||||
@ -110,10 +113,10 @@ R_API bool r_arch_use(RArch *arch, RArchConfig *config) {
|
||||
return true;
|
||||
}
|
||||
if (!config) {
|
||||
return false;
|
||||
// arch->decoder = NULL;
|
||||
return false;
|
||||
}
|
||||
const char *dname = config->decoder ? config->decoder: _find_bestmatch (arch->plugins, config);
|
||||
const char *dname = config->decoder ? config->decoder: _find_bestmatch (arch->plugins, config, name);
|
||||
if (!dname) {
|
||||
return false;
|
||||
}
|
||||
@ -144,7 +147,7 @@ R_API bool r_arch_set_bits(RArch *arch, ut32 bits) {
|
||||
}
|
||||
// r_arch_config_set_bits (arch->cfg, bits);
|
||||
cfg->bits = bits;
|
||||
if (!r_arch_use (arch, cfg)) {
|
||||
if (!r_arch_use (arch, cfg, NULL)) {
|
||||
r_unref (cfg);
|
||||
arch->cfg = NULL;
|
||||
return false;
|
||||
@ -153,17 +156,17 @@ R_API bool r_arch_set_bits(RArch *arch, ut32 bits) {
|
||||
}
|
||||
if (arch->autoselect) {
|
||||
if (arch->current) {
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg);
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg, NULL);
|
||||
arch->cfg->bits = bits;
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg)) {
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg, NULL)) {
|
||||
R_FREE (arch->cfg->decoder);
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
R_FREE (arch->cfg->decoder);
|
||||
arch->cfg->bits = bits;
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, NULL);
|
||||
}
|
||||
arch->cfg->bits = bits;
|
||||
return true;
|
||||
@ -177,7 +180,7 @@ R_API bool r_arch_set_endian(RArch *arch, ut32 endian) {
|
||||
return false;
|
||||
}
|
||||
cfg->endian = endian;
|
||||
if (!r_arch_use (arch, cfg)) {
|
||||
if (!r_arch_use (arch, cfg, NULL)) {
|
||||
r_unref (cfg);
|
||||
arch->cfg = NULL;
|
||||
return false;
|
||||
@ -186,17 +189,17 @@ R_API bool r_arch_set_endian(RArch *arch, ut32 endian) {
|
||||
}
|
||||
if (arch->autoselect) {
|
||||
if (arch->current) {
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg);
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg, NULL);
|
||||
arch->cfg->endian = endian;
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg)) {
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg, NULL)) {
|
||||
R_FREE (arch->cfg->decoder);
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
R_FREE (arch->cfg->decoder);
|
||||
arch->cfg->endian = endian;
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, NULL);
|
||||
}
|
||||
arch->cfg->endian = endian;
|
||||
return true;
|
||||
@ -216,7 +219,7 @@ R_API bool r_arch_set_arch(RArch *arch, char *archname) {
|
||||
}
|
||||
free (cfg->arch);
|
||||
cfg->arch =_arch;
|
||||
if (!r_arch_use (arch, cfg)) {
|
||||
if (!r_arch_use (arch, cfg, archname)) {
|
||||
r_unref (cfg);
|
||||
return false;
|
||||
}
|
||||
@ -224,19 +227,19 @@ R_API bool r_arch_set_arch(RArch *arch, char *archname) {
|
||||
}
|
||||
if (arch->autoselect) {
|
||||
if (arch->current) {
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg);
|
||||
const ut32 score = _rate_compat (arch->current->p, arch->cfg, archname);
|
||||
free (arch->cfg->arch);
|
||||
arch->cfg->arch = _arch;
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg)) {
|
||||
if (!score || score > _rate_compat (arch->current->p, arch->cfg, archname)) {
|
||||
R_FREE (arch->cfg->decoder);
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, archname);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
R_FREE (arch->cfg->decoder);
|
||||
free (arch->cfg->arch);
|
||||
arch->cfg->arch = _arch;
|
||||
return r_arch_use (arch, arch->cfg);
|
||||
return r_arch_use (arch, arch->cfg, archname);
|
||||
}
|
||||
free (arch->cfg->arch);
|
||||
arch->cfg->arch = _arch;
|
||||
@ -292,3 +295,20 @@ R_API void r_arch_free(RArch *arch) {
|
||||
r_unref (arch->cfg);
|
||||
free (arch);
|
||||
}
|
||||
|
||||
#if 0
|
||||
R_API int r_arch_info(RArch *a, int query) {
|
||||
r_return_val_if_fail (a, -1);
|
||||
switch (query) {
|
||||
case R_ANAL_ARCHINFO_MIN_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_MAX_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_INV_OP_SIZE:
|
||||
case R_ANAL_ARCHINFO_ALIGN:
|
||||
if (arch->current && anal->arch->current->archinfo) {
|
||||
return arch->current->archinfo (arch, query);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -111,7 +111,7 @@ R_API bool r_arch_unload_decoder(RArch *arch, const char *dname) {
|
||||
}
|
||||
|
||||
R_API int r_arch_info(RArch *arch, const char *dname, ut32 query) {
|
||||
r_return_val_if_fail (arch && arch->decoders, -1);
|
||||
r_return_val_if_fail (arch, -1);
|
||||
RArchDecoder *decoder = NULL;
|
||||
if (dname) {
|
||||
decoder = (RArchDecoder *)ht_pp_find (arch->decoders, dname, NULL);
|
||||
|
18
libr/arch/encoder.c
Normal file
18
libr/arch/encoder.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* radare2 - LGPL - Copyright 2022 - condret */
|
||||
|
||||
#include <r_arch.h>
|
||||
#include <r_util.h>
|
||||
|
||||
// plaintext to opcdes bytes, returns length
|
||||
// why not returning an RBuffer?
|
||||
// R_API RBuffer *r_arch_encode(RArch *a, ut64 addr, const char *s) { }
|
||||
|
||||
R_API int r_arch_encode(RArch *a, ut64 addr, const char *s, ut8 *outbuf, int outlen) {
|
||||
int res = 0;
|
||||
RArchOpAsmCallback opasm = R_UNWRAP4 (a, current, p, opasm);
|
||||
|
||||
if (opasm) { // a->current && a->current->p && a->current->p->opasm) {
|
||||
res = opasm (a, addr, s, outbuf, outlen);
|
||||
}
|
||||
return res;
|
||||
}
|
@ -2,6 +2,7 @@ r_arch_sources = [
|
||||
'arch.c',
|
||||
'aconfig.c',
|
||||
'decoder.c',
|
||||
'encoder.c',
|
||||
'switchop.c',
|
||||
'archop.c',
|
||||
'archcond.c',
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* radare - LGPL - Copyright 2016-2022 - pancake, condret */
|
||||
|
||||
#include <r_arch.h>
|
||||
#include "../i/i4004/gperfdb.c"
|
||||
|
||||
static bool set_reg_profile(RArchConfig *cfg, RReg *reg) {
|
||||
const char *p =
|
||||
@ -250,6 +251,135 @@ static int i4004_decode(RArchConfig *cfg, RAnalOp *op, ut64 addr, const ut8 *buf
|
||||
return op->size = rlen;
|
||||
}
|
||||
|
||||
static int i4004_anal_opasm(RArch *a, ut64 addr, const char *str, ut8 *outbuf, int outsize) {
|
||||
char *s = strdup (str);
|
||||
r_str_case (s, false);
|
||||
s = r_str_replace (s, "_", "?", false); // mitigate a bug in sdb -C
|
||||
s = r_str_replace (s, ",", " _ ", false);
|
||||
int i, nelems;
|
||||
char **elems = r_str_argv (s, &nelems);
|
||||
RStrBuf *sbuf = r_strbuf_new (elems[0]);
|
||||
for (i = 1; i < nelems; i++) {
|
||||
if (r_is_valid_input_num_value (NULL, elems[i])) {
|
||||
r_strbuf_appendf (sbuf, " 0x%"PFMT64x, r_num_get (NULL, elems[i]));
|
||||
} else {
|
||||
r_strbuf_appendf (sbuf, " %s", elems[i]);
|
||||
}
|
||||
}
|
||||
// this db should be instantiated once on plugin session
|
||||
#if 1
|
||||
Sdb *asm_db = sdb_new0 ();
|
||||
sdb_open_gperf (asm_db, (SdbGperf *)&gperf_i4004);
|
||||
char *hex_output = sdb_get (asm_db, r_strbuf_get (sbuf), NULL);
|
||||
sdb_free (asm_db);
|
||||
r_strbuf_free (sbuf);
|
||||
if (hex_output) {
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
r_hex_str2bin (hex_output, outbuf);
|
||||
free (hex_output);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
if (strlen (elems[0]) != 3) {
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
return 0;
|
||||
}
|
||||
int ret = 0;
|
||||
switch (elems[0][0] << 16 | elems[0][1] << 8 | elems[0][2]) {
|
||||
case 0x6a636e: // jcn
|
||||
if (nelems > 2 && r_is_valid_input_num_value (NULL, elems[1])
|
||||
&& r_is_valid_input_num_value (NULL, elems[2])) {
|
||||
ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x10) {
|
||||
outbuf[0] = 0x10 | (ut8)v;
|
||||
v = r_num_get (NULL, elems[2]);
|
||||
if (v < 0x100) {
|
||||
outbuf[1] = (ut8)v;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x66696d: // fim
|
||||
if (nelems > 3 && !strcmp (elems[2], "_") && r_is_valid_input_num_value (NULL, elems[3])) {
|
||||
const ut64 v = r_num_get (NULL, elems[3]);
|
||||
if (v < 0x100) {
|
||||
ret = 2;
|
||||
if (!strcmp (elems[1], "r0r1")) {
|
||||
outbuf[0] = 0x20;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r2r3")) {
|
||||
outbuf[0] = 0x22;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r4r5")) {
|
||||
outbuf[0] = 0x24;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r6r7")) {
|
||||
outbuf[0] = 0x26;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r8r9")) {
|
||||
outbuf[0] = 0x28;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r10r11")) {
|
||||
outbuf[0] = 0x2a;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r12r14")) {
|
||||
outbuf[0] = 0x2c;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else if (!strcmp (elems[1], "r14r15")) {
|
||||
outbuf[0] = 0x2e;
|
||||
outbuf[1] = (ut8)v;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x6a756e: // jun
|
||||
if (nelems > 1 && r_is_valid_input_num_value (NULL, elems[1])) {
|
||||
const ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x1000) {
|
||||
outbuf[0] = 0x40 | (v & 0xf00) >> 8;
|
||||
outbuf[1] = v & 0xff;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x6a6d73: // jms
|
||||
if (nelems > 1 && r_is_valid_input_num_value (NULL, elems[1])) {
|
||||
const ut64 v = r_num_get (NULL, elems[1]);
|
||||
if (v < 0x1000) {
|
||||
outbuf[0] = 0x50 | (v & 0xf00) >> 8;
|
||||
outbuf[1] = v & 0xff;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x69737a: // isz
|
||||
if (nelems > 3 && elems[1][0] == 'r' && r_is_valid_input_num_value (NULL, &elems[1][1])
|
||||
&& !strcmp (elems[2], "_") && r_is_valid_input_num_value (NULL, elems[3])) {
|
||||
ut64 v = r_num_get (NULL, &elems[1][1]);
|
||||
if (v < 0x10) {
|
||||
outbuf[0] = 0x70 | (ut8)v;
|
||||
v = r_num_get (NULL, elems[3]);
|
||||
if (v < 0x100) {
|
||||
outbuf[1] = (ut8)v;
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
r_str_argv_free (elems);
|
||||
free (s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RArchPlugin r_arch_plugin_i4004 = {
|
||||
.name = "i4004",
|
||||
.desc = "i4004 decoder plugin",
|
||||
@ -261,6 +391,7 @@ RArchPlugin r_arch_plugin_i4004 = {
|
||||
.esil = false,
|
||||
.author = "pancake, condret",
|
||||
.decode = &i4004_decode,
|
||||
.opasm = &i4004_anal_opasm,
|
||||
.set_reg_profile = &set_reg_profile
|
||||
};
|
||||
|
||||
|
150
libr/asm/asm.c
150
libr/asm/asm.c
@ -316,7 +316,7 @@ R_API bool r_asm_use_assembler(RAsm *a, const char *name) {
|
||||
RAsmPlugin *h;
|
||||
RListIter *iter;
|
||||
if (a) {
|
||||
if (name && *name) {
|
||||
if (R_STR_ISNOTEMPTY (name)) {
|
||||
r_list_foreach (a->plugins, iter, h) {
|
||||
if (h->assemble && !strcmp (h->name, name)) {
|
||||
a->acur = h;
|
||||
@ -342,7 +342,7 @@ static void load_asm_descriptions(RAsm *a, RAsmPlugin *p) {
|
||||
arch = a->config->cpu;
|
||||
}
|
||||
#if HAVE_GPERF
|
||||
SdbGperf *gp = r_asm_get_gperf (arch); // p->name);
|
||||
SdbGperf *gp = r_asm_get_gperf (arch);
|
||||
if (gp) {
|
||||
sdb_free (a->pair);
|
||||
a->pair = sdb_new0 ();
|
||||
@ -353,8 +353,12 @@ static void load_asm_descriptions(RAsm *a, RAsmPlugin *p) {
|
||||
char *r2prefix = r_str_r2_prefix (R2_SDB_OPCODES);
|
||||
char *file = r_str_newf ("%s/%s.sdb", r_str_getf (r2prefix), arch);
|
||||
if (file) {
|
||||
#if 0
|
||||
sdb_reset (a->pair);
|
||||
#else
|
||||
sdb_free (a->pair);
|
||||
a->pair = sdb_new (NULL, file, 0);
|
||||
#endif
|
||||
free (file);
|
||||
}
|
||||
free (r2prefix);
|
||||
@ -369,54 +373,56 @@ R_API bool r_asm_use(RAsm *a, const char *name) {
|
||||
}
|
||||
RAsmPlugin *h;
|
||||
RListIter *iter;
|
||||
char *dotname = strdup (name);
|
||||
char *vv = strchr (dotname, '.');
|
||||
if (vv) {
|
||||
*vv = 0;
|
||||
} else {
|
||||
R_FREE (dotname);
|
||||
}
|
||||
r_list_foreach (a->plugins, iter, h) {
|
||||
if (h->arch) {
|
||||
if (!strcmp (h->name, name)) {
|
||||
if (!a->cur || (a->cur && strcmp (a->cur->arch, h->arch))) {
|
||||
load_asm_descriptions (a, h);
|
||||
r_asm_set_cpu (a, NULL);
|
||||
}
|
||||
if (!strcmp (h->name, name)) {
|
||||
if (!a->cur || (a->cur && h->arch && strcmp (a->cur->arch, h->arch))) {
|
||||
load_asm_descriptions (a, h);
|
||||
r_asm_set_cpu (a, NULL);
|
||||
}
|
||||
a->cur = h;
|
||||
return true;
|
||||
}
|
||||
if (dotname && h->arch && !strcmp (dotname, h->arch)) {
|
||||
char *arch = r_str_ndup (name, vv - name);
|
||||
#if 0
|
||||
r_arch_config_set_cpu (a->config, arch);
|
||||
// r_asm_set_cpu (a, arch);
|
||||
// h->arch = name;
|
||||
#else
|
||||
r_asm_set_cpu (a, arch);
|
||||
#endif
|
||||
a->cur = h;
|
||||
load_asm_descriptions (a, h);
|
||||
free (arch);
|
||||
return true;
|
||||
}
|
||||
#if 0
|
||||
} else if (!strcmp (name, h->name)) {
|
||||
#if 0
|
||||
r_arch_config_set_cpu (a->config, NULL);
|
||||
#else
|
||||
h->arch = name; // leaks wtf is this shit
|
||||
r_asm_set_cpu (a, NULL);
|
||||
#endif
|
||||
a->cur = h;
|
||||
load_asm_descriptions (a, h);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// resolve asm plugin by name, support multi-arch assemblers
|
||||
char *vv = strchr (name, '.');
|
||||
if (vv) {
|
||||
if (!strcmp (vv + 1, h->name)) {
|
||||
char *arch = r_str_ndup (name, vv - name);
|
||||
#if 0
|
||||
r_arch_config_set_cpu (a->config, arch);
|
||||
// r_asm_set_cpu (a, arch);
|
||||
// h->arch = name;
|
||||
#else
|
||||
r_asm_set_cpu (a, arch);
|
||||
#endif
|
||||
a->cur = h;
|
||||
load_asm_descriptions (a, h);
|
||||
free (arch);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!strcmp (name, h->name)) {
|
||||
#if 0
|
||||
r_arch_config_set_cpu (a->config, NULL);
|
||||
#else
|
||||
h->arch = name;
|
||||
r_asm_set_cpu (a, NULL);
|
||||
#endif
|
||||
a->cur = h;
|
||||
load_asm_descriptions (a, h);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (a->analb.anal) {
|
||||
if (a->analb.use (a->analb.anal, name)) {
|
||||
load_asm_descriptions (a, NULL);
|
||||
// return true;
|
||||
} else {
|
||||
R_LOG_ERROR ("Cannot find '%s' asm/arch/anal plugin. See rasm2 -L and rasm2 -LL", name);
|
||||
R_LOG_ERROR ("Cannot find '%s' asm/arch/anal plugin. See rasm2 -L, -LL or -LLL", name);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
@ -425,7 +431,7 @@ R_API bool r_asm_use(RAsm *a, const char *name) {
|
||||
a->pair = NULL;
|
||||
#endif
|
||||
if (strcmp (name, "null")) {
|
||||
return r_asm_use (a, "null");
|
||||
return r_asm_use (a, "null"); // x86.nz");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -581,31 +587,41 @@ R_API int r_asm_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
|
||||
typedef int (*Ase)(RAsm *a, RAsmOp *op, const char *buf);
|
||||
|
||||
static bool assemblerMatches(RAsm *a, RAsmPlugin *h) {
|
||||
static bool assemblerMatches(RAsm *a, RAsmPlugin *h, const char *ends_with) {
|
||||
const char *arch = R_UNWRAP3 (a, config, arch);
|
||||
if (!a || !h->arch || !h->assemble || !has_bits (h, a->config->bits)) {
|
||||
return false;
|
||||
}
|
||||
return (a->cur->arch && !strncmp (a->config->arch, h->arch, strlen (a->cur->arch)));
|
||||
const char *cur_arch = R_UNWRAP3 (a, cur, arch);
|
||||
if (!strcmp (h->arch, arch)) {
|
||||
if (ends_with) {
|
||||
return r_str_endswith (h->name, ends_with);
|
||||
}
|
||||
if ((cur_arch && r_str_startswith (cur_arch, h->arch))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Ase findAssembler(RAsm *a, const char *kw) {
|
||||
RAsmPlugin *h;
|
||||
RListIter *iter;
|
||||
if (a->acur && a->acur->assemble) {
|
||||
return a->acur->assemble;
|
||||
}
|
||||
r_list_foreach (a->plugins, iter, h) {
|
||||
if (assemblerMatches (a, h)) {
|
||||
if (kw) {
|
||||
if (strstr (h->name, kw)) {
|
||||
return h->assemble;
|
||||
static Ase find_assembler(RAsm *a, const char *kw) {
|
||||
RAsmAssembleCallback aac = R_UNWRAP3 (a, acur, assemble);
|
||||
if (!aac) {
|
||||
RAsmPlugin *h;
|
||||
RListIter *iter;
|
||||
r_list_foreach (a->plugins, iter, h) {
|
||||
if (assemblerMatches (a, h, kw)) {
|
||||
if (kw) {
|
||||
if (r_str_endswith (h->name, kw)) {
|
||||
aac = h->assemble;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return h->assemble;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return aac;
|
||||
}
|
||||
|
||||
static char *replace_directives_for(char *str, const char *token) {
|
||||
@ -620,7 +636,7 @@ static char *replace_directives_for(char *str, const char *token) {
|
||||
if (p) {
|
||||
char *nl = strchr (p, '\n');
|
||||
if (nl) {
|
||||
*nl ++ = 0;
|
||||
*nl++ = 0;
|
||||
}
|
||||
char _ = *p;
|
||||
*p = 0;
|
||||
@ -675,17 +691,17 @@ R_API int r_asm_assemble(RAsm *a, RAsmOp *op, const char *buf) {
|
||||
if (a->ifilter) {
|
||||
r_parse_parse (a->ifilter, buf, b);
|
||||
}
|
||||
r_str_case (b, 0); // to-lower
|
||||
memset (op, 0, sizeof (RAsmOp));
|
||||
r_str_case (b, false); // to-lower
|
||||
r_asm_op_init (op);
|
||||
if (a->cur) {
|
||||
Ase ase = NULL;
|
||||
if (!a->cur->assemble) {
|
||||
Ase ase = R_UNWRAP3 (a, cur, assemble);
|
||||
if (!ase) {
|
||||
/* find callback if no assembler support in current plugin */
|
||||
ase = findAssembler (a, ".ks");
|
||||
ase = find_assembler (a, ".ks");
|
||||
if (!ase) {
|
||||
ase = findAssembler (a, ".nz");
|
||||
ase = find_assembler (a, ".nz");
|
||||
if (!ase) {
|
||||
ase = findAssembler (a, NULL);
|
||||
ase = find_assembler (a, NULL);
|
||||
}
|
||||
}
|
||||
if (!ase && a->analb.anal) {
|
||||
@ -934,7 +950,7 @@ R_API RAsmCode *r_asm_massemble(RAsm *a, const char *assembly) {
|
||||
if (cptr && ptr && cptr < ptr) {
|
||||
likely_comment = false;
|
||||
for (cptr += 1; cptr < ptr ; cptr += 1) {
|
||||
if (! isspace ((unsigned char) *cptr)) {
|
||||
if (! isspace ((int) *cptr)) {
|
||||
likely_comment = true;
|
||||
break;
|
||||
}
|
||||
@ -955,7 +971,7 @@ R_API RAsmCode *r_asm_massemble(RAsm *a, const char *assembly) {
|
||||
if (!*ptr_start) {
|
||||
continue;
|
||||
}
|
||||
linenum ++;
|
||||
linenum++;
|
||||
/* labels */
|
||||
if (labels && (ptr = strchr (ptr_start, ':'))) {
|
||||
bool is_a_label = true;
|
||||
|
@ -987,16 +987,18 @@ static cache_imgxtr_t *read_cache_imgextra(RBuffer *cache_buf, cache_hdr_t *hdr,
|
||||
|
||||
static char *get_lib_name(RBuffer *cache_buf, cache_img_t *img) {
|
||||
char file[256];
|
||||
char *lib_name = file;
|
||||
const char *lib_name = file;
|
||||
if (r_buf_read_at (cache_buf, img->pathFileOffset, (ut8*) &file, sizeof (file)) == sizeof (file)) {
|
||||
file[255] = 0;
|
||||
/*char * last_slash = strrchr (file, '/');
|
||||
file[sizeof (file) - 1] = 0; // wtf
|
||||
#if 0
|
||||
char * last_slash = strrchr (file, '/');
|
||||
if (last_slash && *last_slash) {
|
||||
lib_name = last_slash + 1;
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
return strdup (lib_name);
|
||||
}
|
||||
return strdup ("FAIL");
|
||||
return strdup ("FAIL"); /// XXX return NULL instead
|
||||
}
|
||||
|
||||
static int string_contains(const void *a, const void *b) {
|
||||
|
@ -154,12 +154,14 @@ static bool nextpal_item(RCore *core, PJ *pj, int mode, const char *file) {
|
||||
static bool cmd_load_theme(RCore *core, const char *_arg) {
|
||||
bool failed = false;
|
||||
char *path;
|
||||
if (!_arg || !*_arg) {
|
||||
if (R_STR_ISEMPTY (_arg)) {
|
||||
return false;
|
||||
}
|
||||
if (!strcmp (_arg, "default")) {
|
||||
free (core->theme);
|
||||
core->theme = strdup (_arg);
|
||||
if (_arg != core->theme) {
|
||||
free (core->theme);
|
||||
core->theme = strdup (_arg);
|
||||
}
|
||||
r_cons_pal_init (core->cons->context);
|
||||
return true;
|
||||
}
|
||||
|
@ -1885,7 +1885,6 @@ extern RAnalPlugin r_anal_plugin_dalvik;
|
||||
extern RAnalPlugin r_anal_plugin_ebc;
|
||||
extern RAnalPlugin r_anal_plugin_gb;
|
||||
extern RAnalPlugin r_anal_plugin_h8300;
|
||||
extern RAnalPlugin r_anal_plugin_i4004;
|
||||
extern RAnalPlugin r_anal_plugin_i8080;
|
||||
extern RAnalPlugin r_anal_plugin_java;
|
||||
extern RAnalPlugin r_anal_plugin_kvx;
|
||||
|
@ -93,6 +93,8 @@ typedef struct r_arch_t {
|
||||
bool autoselect;
|
||||
} RArch;
|
||||
|
||||
typedef int (*RArchOpAsmCallback)(RArch *a, ut64 addr, const char *str, ut8 *outbuf, int outlen);
|
||||
|
||||
typedef struct r_arch_plugin_t {
|
||||
char *name;
|
||||
char *desc;
|
||||
@ -110,6 +112,7 @@ typedef struct r_arch_plugin_t {
|
||||
int (*info)(RArchConfig *cfg, ut32 query);
|
||||
int (*decode)(RArchConfig *cfg, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask, void *user);
|
||||
bool (*set_reg_profile)(RArchConfig *cfg, struct r_reg_t *reg);
|
||||
RArchOpAsmCallback opasm;
|
||||
//TODO: reenable this later
|
||||
// bool (*esil_init)(RAnalEsil *esil);
|
||||
// void (*esil_fini)(RAnalEsil *esil);
|
||||
@ -122,13 +125,14 @@ R_API bool r_arch_use_decoder(RArch *arch, const char *dname);
|
||||
R_API bool r_arch_unload_decoder(RArch *arch, const char *dname);
|
||||
R_API int r_arch_info(RArch *arch, const char *dname, ut32 query);
|
||||
R_API int r_arch_decode(RArch *arch, const char *dname, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask);
|
||||
R_API int r_arch_encode(RArch *a, ut64 addr, const char *s, ut8 *outbuf, int outlen);
|
||||
R_API bool r_arch_set_reg_profile(RArch *arch, const char *dname, struct r_reg_t *reg);
|
||||
//R_API bool r_arch_esil_init(RArch *arch, const char *dname, RAnalEsil *esil);
|
||||
//R_API void r_arch_esil_fini(RArch *arch, const char *dname, RAnalEsil *esil);
|
||||
|
||||
// arch.c
|
||||
R_API RArch *r_arch_new(void);
|
||||
R_API bool r_arch_use(RArch *arch, RArchConfig *config);
|
||||
R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name);
|
||||
R_API bool r_arch_set_bits(RArch *arch, ut32 bits);
|
||||
R_API bool r_arch_set_endian(RArch *arch, ut32 endian);
|
||||
R_API bool r_arch_set_arch(RArch *arch, char *archname);
|
||||
|
@ -97,6 +97,7 @@ typedef struct r_asm_t {
|
||||
} RAsm;
|
||||
|
||||
typedef bool (*RAsmModifyCallback)(RAsm *a, ut8 *buf, int field, ut64 val);
|
||||
typedef int (*RAsmAssembleCallback)(RAsm *a, RAsmOp *op, const char *buf);
|
||||
|
||||
typedef struct r_asm_plugin_t {
|
||||
const char *name;
|
||||
@ -112,7 +113,8 @@ typedef struct r_asm_plugin_t {
|
||||
bool (*init)(void *user);
|
||||
bool (*fini)(void *user);
|
||||
int (*disassemble)(RAsm *a, RAsmOp *op, const ut8 *buf, int len);
|
||||
int (*assemble)(RAsm *a, RAsmOp *op, const char *buf);
|
||||
|
||||
RAsmAssembleCallback assemble;
|
||||
RAsmModifyCallback modify;
|
||||
char *(*mnemonics)(RAsm *a, int id, bool json);
|
||||
const char *features;
|
||||
@ -129,12 +131,14 @@ R_API void r_asm_set_user_ptr(RAsm *a, void *user);
|
||||
R_API bool r_asm_add(RAsm *a, RAsmPlugin *foo);
|
||||
R_API bool r_asm_setup(RAsm *a, const char *arch, int bits, int big_endian);
|
||||
R_API bool r_asm_is_valid(RAsm *a, const char *name);
|
||||
|
||||
R_API bool r_asm_use(RAsm *a, const char *name);
|
||||
R_API bool r_asm_use_assembler(RAsm *a, const char *name);
|
||||
R_API bool r_asm_set_arch(RAsm *a, const char *name, int bits);
|
||||
R_API int r_asm_set_bits(RAsm *a, int bits);
|
||||
R_API void r_asm_set_cpu(RAsm *a, const char *cpu);
|
||||
R_API bool r_asm_set_big_endian(RAsm *a, bool big_endian);
|
||||
|
||||
R_API bool r_asm_set_syntax(RAsm *a, int syntax);
|
||||
R_API int r_asm_syntax_from_string(const char *name);
|
||||
R_API int r_asm_set_pc(RAsm *a, ut64 pc);
|
||||
|
@ -231,6 +231,11 @@ typedef struct _utX {
|
||||
#define R_PACKED( __Declaration__ ) __Declaration__ __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#define R_UNWRAP2(a,b) ((a)? a->b: NULL)
|
||||
#define R_UNWRAP3(a,b,c) ((a)? a->b? a->b->c: NULL: NULL)
|
||||
#define R_UNWRAP4(a,b,c,d) ((a)? a->b? a->b->c? a->b->c->d: NULL: NULL: NULL)
|
||||
#define R_UNWRAP5(a,b,c,d,e) ((a)? a->b? a->b->c? a->b->c->d: a->b->c->d->e: NULL: NULL: NULL: NULL)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define R_UNUSED __attribute__((__unused__))
|
||||
#define R_WEAK __attribute__ ((weak))
|
||||
|
@ -150,7 +150,6 @@ anal_plugins += [
|
||||
'evm_cs',
|
||||
'gb',
|
||||
'h8300',
|
||||
'i4004',
|
||||
'i8080',
|
||||
'java',
|
||||
'kvx',
|
||||
|
Loading…
Reference in New Issue
Block a user