Remove globals in RzAsm plugins (#4114)

* Remove globals in RzAsm plugins

* Fix breakage due small mistakes
This commit is contained in:
Giovanni 2024-01-17 08:02:23 +08:00 committed by GitHub
parent 5b36c7c6e0
commit 0b54b57432
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 593 additions and 566 deletions

View file

@ -183,14 +183,17 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
rz_str_cpy(insn->mnemonic, tmpstr);
free(tmpstr);
}
char *buf_asm = sdb_fmt("%s%s%s",
char *buf_asm = rz_str_newf("%s%s%s",
insn->mnemonic,
insn->op_str[0] ? " " : "",
insn->op_str);
if (!disp_hash) {
rz_str_replace_char(buf_asm, '#', 0);
if (buf_asm) {
if (!disp_hash) {
rz_str_replace_char(buf_asm, '#', 0);
}
rz_strbuf_set(&op->buf_asm, buf_asm);
free(buf_asm);
}
rz_strbuf_set(&op->buf_asm, buf_asm);
}
cs_free(insn, n);
beach:

View file

@ -4,84 +4,89 @@
#include <rz_asm.h>
#include <rz_lib.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) {
static int chip8_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *b, int l) {
ut16 opcode = rz_read_be16(b);
uint8_t x = (opcode >> 8) & 0x0F;
uint8_t y = (opcode >> 4) & 0x0F;
uint8_t nibble = opcode & 0x0F;
uint16_t nnn = opcode & 0x0FFF;
uint8_t kk = opcode & 0xFF;
const char *buf_asm = "invalid";
char *buf_asm = NULL;
switch (opcode & 0xF000) {
case 0x0000:
if (opcode == 0x00E0) {
buf_asm = "cls";
buf_asm = strdup("cls");
} else if (opcode == 0x00EE) {
buf_asm = "ret";
buf_asm = strdup("ret");
} else if ((opcode & 0xFFF0) == 0x00C0) {
buf_asm = sdb_fmt("scd 0x%01x", nibble);
buf_asm = rz_str_newf("scd 0x%01x", nibble);
} else if (opcode == 0x00FB) {
buf_asm = "scr";
buf_asm = strdup("scr");
} else if (opcode == 0x00FC) {
buf_asm = "scl";
buf_asm = strdup("scl");
} else if (opcode == 0x00FD) {
buf_asm = "exit";
buf_asm = strdup("exit");
} else if (opcode == 0x00FE) {
buf_asm = "low";
buf_asm = strdup("low");
} else if (opcode == 0x00FF) {
buf_asm = "high";
buf_asm = strdup("high");
}
break;
case 0x1000: buf_asm = sdb_fmt("jp 0x%03x", nnn); break;
case 0x2000: buf_asm = sdb_fmt("call 0x%03x", nnn); break;
case 0x3000: buf_asm = sdb_fmt("se v%1x, 0x%02x", x, kk); break;
case 0x4000: buf_asm = sdb_fmt("sne v%1x, 0x%02x", x, kk); break;
case 0x5000: buf_asm = sdb_fmt("se v%1x, v%1x", x, y); break;
case 0x6000: buf_asm = sdb_fmt("ld v%1x, 0x%02x", x, kk); break;
case 0x7000: buf_asm = sdb_fmt("add v%1x, 0x%02x", x, kk); break;
case 0x1000: buf_asm = rz_str_newf("jp 0x%03x", nnn); break;
case 0x2000: buf_asm = rz_str_newf("call 0x%03x", nnn); break;
case 0x3000: buf_asm = rz_str_newf("se v%1x, 0x%02x", x, kk); break;
case 0x4000: buf_asm = rz_str_newf("sne v%1x, 0x%02x", x, kk); break;
case 0x5000: buf_asm = rz_str_newf("se v%1x, v%1x", x, y); break;
case 0x6000: buf_asm = rz_str_newf("ld v%1x, 0x%02x", x, kk); break;
case 0x7000: buf_asm = rz_str_newf("add v%1x, 0x%02x", x, kk); break;
case 0x8000: {
switch (nibble) {
case 0x0: buf_asm = sdb_fmt("ld v%1x, v%1x", x, y); break;
case 0x1: buf_asm = sdb_fmt("or v%1x, v%1x", x, y); break;
case 0x2: buf_asm = sdb_fmt("and v%1x, v%1x", x, y); break;
case 0x3: buf_asm = sdb_fmt("xor v%1x, v%1x", x, y); break;
case 0x4: buf_asm = sdb_fmt("add v%1x, v%1x", x, y); break;
case 0x5: buf_asm = sdb_fmt("sub v%1x, v%1x", x, y); break;
case 0x6: buf_asm = sdb_fmt("shr v%1x, v%1x", x, y); break;
case 0x7: buf_asm = sdb_fmt("subn v%1x, v%1x", x, y); break;
case 0xE: buf_asm = sdb_fmt("shl v%1x, v%1x", x, y); break;
case 0x0: buf_asm = rz_str_newf("ld v%1x, v%1x", x, y); break;
case 0x1: buf_asm = rz_str_newf("or v%1x, v%1x", x, y); break;
case 0x2: buf_asm = rz_str_newf("and v%1x, v%1x", x, y); break;
case 0x3: buf_asm = rz_str_newf("xor v%1x, v%1x", x, y); break;
case 0x4: buf_asm = rz_str_newf("add v%1x, v%1x", x, y); break;
case 0x5: buf_asm = rz_str_newf("sub v%1x, v%1x", x, y); break;
case 0x6: buf_asm = rz_str_newf("shr v%1x, v%1x", x, y); break;
case 0x7: buf_asm = rz_str_newf("subn v%1x, v%1x", x, y); break;
case 0xE: buf_asm = rz_str_newf("shl v%1x, v%1x", x, y); break;
}
} break;
case 0x9000: buf_asm = sdb_fmt("sne v%1x, v%1x", x, y); break;
case 0xA000: buf_asm = sdb_fmt("ld i, 0x%03x", nnn); break;
case 0xB000: buf_asm = sdb_fmt("jp v0, 0x%03x", nnn); break;
case 0xC000: buf_asm = sdb_fmt("rnd v%1x, 0x%02x", x, kk); break;
case 0xD000: buf_asm = sdb_fmt("drw v%1x, v%1x, 0x%01x", x, y, nibble); break;
case 0x9000: buf_asm = rz_str_newf("sne v%1x, v%1x", x, y); break;
case 0xA000: buf_asm = rz_str_newf("ld i, 0x%03x", nnn); break;
case 0xB000: buf_asm = rz_str_newf("jp v0, 0x%03x", nnn); break;
case 0xC000: buf_asm = rz_str_newf("rnd v%1x, 0x%02x", x, kk); break;
case 0xD000: buf_asm = rz_str_newf("drw v%1x, v%1x, 0x%01x", x, y, nibble); break;
case 0xE000: {
if (kk == 0x9E) {
buf_asm = sdb_fmt("skp v%1x", x);
buf_asm = rz_str_newf("skp v%1x", x);
} else if (kk == 0xA1) {
buf_asm = sdb_fmt("sknp v%1x", x);
buf_asm = rz_str_newf("sknp v%1x", x);
}
} break;
case 0xF000: {
switch (kk) {
case 0x07: buf_asm = sdb_fmt("ld v%1x, dt", x); break;
case 0x0A: buf_asm = sdb_fmt("ld v%1x, k", x); break;
case 0x15: buf_asm = sdb_fmt("ld dt, v%1x", x); break;
case 0x18: buf_asm = sdb_fmt("ld st, v%1x", x); break;
case 0x1E: buf_asm = sdb_fmt("add i, v%1x", x); break;
case 0x29: buf_asm = sdb_fmt("ld f, v%1x", x); break;
case 0x33: buf_asm = sdb_fmt("ld b, v%1x", x); break;
case 0x55: buf_asm = sdb_fmt("ld [i], v%1x", x); break;
case 0x65: buf_asm = sdb_fmt("ld v%1x, [i]", x); break;
case 0x30: buf_asm = sdb_fmt("ld hf, v%1x", x); break;
case 0x75: buf_asm = sdb_fmt("ld r, v%1x", x); break;
case 0x85: buf_asm = sdb_fmt("ld v%1x, r", x); break;
case 0x07: buf_asm = rz_str_newf("ld v%1x, dt", x); break;
case 0x0A: buf_asm = rz_str_newf("ld v%1x, k", x); break;
case 0x15: buf_asm = rz_str_newf("ld dt, v%1x", x); break;
case 0x18: buf_asm = rz_str_newf("ld st, v%1x", x); break;
case 0x1E: buf_asm = rz_str_newf("add i, v%1x", x); break;
case 0x29: buf_asm = rz_str_newf("ld f, v%1x", x); break;
case 0x33: buf_asm = rz_str_newf("ld b, v%1x", x); break;
case 0x55: buf_asm = rz_str_newf("ld [i], v%1x", x); break;
case 0x65: buf_asm = rz_str_newf("ld v%1x, [i]", x); break;
case 0x30: buf_asm = rz_str_newf("ld hf, v%1x", x); break;
case 0x75: buf_asm = rz_str_newf("ld r, v%1x", x); break;
case 0x85: buf_asm = rz_str_newf("ld v%1x, r", x); break;
}
} break;
}
rz_strbuf_set(&op->buf_asm, buf_asm);
if (!buf_asm) {
rz_strbuf_set(&op->buf_asm, "invalid");
} else {
rz_strbuf_set(&op->buf_asm, buf_asm);
free(buf_asm);
}
op->size = 2;
return op->size;
}
@ -92,7 +97,7 @@ RzAsmPlugin rz_asm_plugin_chip8 = {
.license = "LGPL3",
.bits = 32,
.desc = "Chip8 disassembler",
.disassemble = &disassemble,
.disassemble = &chip8_disassemble,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -8,10 +8,14 @@
#include <rz_asm.h>
#include <cr16_disas.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct cr16_cmd cmd;
static int cr16_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct cr16_cmd cmd = { 0 };
int ret = cr16_decode_command(buf, &cmd, len);
rz_strbuf_set(&op->buf_asm, sdb_fmt("%s %s", cmd.instr, cmd.operands));
if (ret > -1) {
rz_strbuf_initf(&op->buf_asm, "%s %s", cmd.instr, cmd.operands);
} else {
rz_strbuf_set(&op->buf_asm, "invalid");
}
return op->size = ret;
}
@ -22,7 +26,7 @@ RzAsmPlugin rz_asm_plugin_cr16 = {
.arch = "cr16",
.bits = 16,
.endian = RZ_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble
.disassemble = &cr16_disassemble
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -22,7 +22,7 @@ static int dalvik_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
char *flag_str = NULL;
a->dataalign = 2;
const char *buf_asm = NULL;
char *buf_asm = NULL;
if (buf[0] == 0x00) { /* nop */
if (len < 2) {
return -1;
@ -35,7 +35,7 @@ static int dalvik_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
{
ut16 array_size = buf[2] | (buf[3] << 8);
int first_key = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
buf_asm = sdb_fmt("packed-switch-payload %d, %d", array_size, first_key);
buf_asm = rz_str_newf("packed-switch-payload %d, %d", array_size, first_key);
size = 8;
payload = 2 * (array_size * 2);
len = 0;
@ -47,7 +47,7 @@ static int dalvik_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
// int[size] relative offsets
{
ut16 array_size = buf[2] | (buf[3] << 8);
buf_asm = sdb_fmt("sparse-switch-payload %d", array_size);
buf_asm = rz_str_newf("sparse-switch-payload %d", array_size);
size = 4;
payload = 2 * (array_size * 4);
len = 0;
@ -60,7 +60,7 @@ static int dalvik_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
if (len > 7) {
ut16 elem_width = buf[2] | (buf[3] << 8);
ut32 array_size = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
buf_asm = sdb_fmt("fill-array-data-payload %d, %d", elem_width, array_size);
buf_asm = rz_str_newf("fill-array-data-payload %d, %d", elem_width, array_size);
payload = array_size * elem_width;
}
size = 8;
@ -73,6 +73,7 @@ static int dalvik_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
}
if (buf_asm) {
rz_strbuf_set(&op->buf_asm, buf_asm);
RZ_FREE(buf_asm);
}
strasm = NULL;
if (size <= len) {

View file

@ -12,10 +12,15 @@
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
ebc_command_t cmd = { { 0 }, { 0 } };
int ret = ebc_decode_command(buf, len, &cmd);
const char *buf_asm = (cmd.operands[0])
? sdb_fmt("%s %s", cmd.instr, cmd.operands)
: cmd.instr;
rz_asm_op_set_asm(op, buf_asm);
if (cmd.operands[0]) {
char *buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
} else {
rz_asm_op_set_asm(op, cmd.instr);
}
return op->size = ret;
}

View file

@ -11,7 +11,11 @@
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct h8300_cmd cmd;
int ret = h8300_decode_command(buf, &cmd);
rz_strbuf_set(&op->buf_asm, sdb_fmt("%s %s", cmd.instr, cmd.operands));
char *buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
if (buf_asm) {
rz_strbuf_set(&op->buf_asm, buf_asm);
free(buf_asm);
}
return op->size = ret;
}

View file

@ -3,11 +3,11 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
#include "cs_helper.h"
static csh cd = 0;
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(m680x);
static int m680xmode(const char *str) {
static cs_mode m680x_mode(const char *str) {
if (!str) {
return CS_MODE_M680X_6800;
}
@ -39,55 +39,34 @@ static int m680xmode(const char *str) {
return CS_MODE_M680X_6800;
}
typedef struct {
int omode;
} M680xContext;
static int m680x_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
static bool m680x_init(void **user) {
M680xContext *ctx = RZ_NEW0(M680xContext);
rz_return_val_if_fail(ctx, false);
ctx->omode = 0;
*user = ctx;
return true;
}
static bool the_end(void *p) {
M680xContext *ctx = (M680xContext *)p;
if (cd) {
cs_close(&cd);
cd = 0;
}
if (ctx) {
RZ_FREE(ctx);
}
return true;
}
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
M680xContext *ctx = (M680xContext *)a->plugin_data;
int omode = ctx->omode;
int mode, n, ret;
int n, ret;
ut64 off = a->pc;
cs_mode mode;
cs_insn *insn = NULL;
mode = m680xmode(a->cpu);
if (cd && mode != omode) {
cs_close(&cd);
cd = 0;
}
mode = m680x_mode(a->cpu);
op->size = 0;
omode = mode;
if (cd == 0) {
ret = cs_open(CS_ARCH_M680X, mode, &cd);
if (ret) {
return 0;
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn);
if (!ctx->handle) {
ret = cs_open(CS_ARCH_M680X, mode, &ctx->handle);
if (ret) {
return -1;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
n = cs_disasm(ctx->handle, (const ut8 *)buf, len, off, 1, &insn);
if (n > 0) {
if (insn->size > 0) {
op->size = insn->size;
char *buf_asm = sdb_fmt("%s%s%s",
char *buf_asm = rz_str_newf("%s%s%s",
insn->mnemonic, insn->op_str[0] ? " " : "",
insn->op_str);
char *ptrstr = strstr(buf_asm, "ptr ");
@ -95,6 +74,7 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
memmove(ptrstr, ptrstr + 4, strlen(ptrstr + 4) + 1);
}
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
cs_free(insn, n);
}
@ -110,8 +90,9 @@ RzAsmPlugin rz_asm_plugin_m680x_cs = {
.bits = 8 | 32,
.endian = RZ_SYS_ENDIAN_LITTLE,
.init = m680x_init,
.fini = the_end,
.disassemble = &disassemble,
.fini = m680x_fini,
.disassemble = &m680x_disassemble,
.mnemonics = m680x_mnemonics,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -17,35 +17,22 @@
#endif
#if CAPSTONE_HAS_M68K
#include "cs_helper.h"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(m68k);
// Size of the longest instruction in bytes
#define M68K_LONGEST_INSTRUCTION 10
static bool check_features(RzAsm *a, cs_insn *insn);
static csh cd = 0;
#include "cs_mnemonics.c"
typedef struct {
int omode;
int obits;
} M68kContext;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
M68kContext *ctx = (M68kContext *)a->plugin_data;
const char *buf_asm = NULL;
int omode = ctx->omode;
int obits = ctx->obits;
static int m68k_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
if (!buf) {
return -1;
}
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
char *buf_asm = NULL;
cs_insn *insn = NULL;
omode = -1;
obits = 32;
int ret = 0, n = 0;
cs_mode mode = a->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN;
if (mode != omode || a->bits != obits) {
cs_close(&cd);
cd = 0; // unnecessary
omode = mode;
obits = a->bits;
}
// replace this with the asm.features?
if (a->cpu && strstr(a->cpu, "68000")) {
@ -69,27 +56,30 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
if (op) {
op->size = 4;
}
if (cd == 0) {
ret = cs_open(CS_ARCH_M68K, mode, &cd);
if (mode != ctx->omode) {
cs_close(&ctx->handle);
ctx->handle = 0;
ctx->omode = -1;
}
if (!ctx->handle) {
ret = cs_open(CS_ARCH_M68K, mode, &ctx->handle);
if (ret) {
ret = -1;
goto beach;
}
ctx->omode = mode;
}
if (a->features && *a->features) {
cs_option(cd, CS_OPT_DETAIL, CS_OPT_ON);
if (RZ_STR_ISNOTEMPTY(a->features)) {
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_ON);
} else {
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
}
if (!buf) {
goto beach;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
ut8 mybuf[M68K_LONGEST_INSTRUCTION] = { 0 };
int mylen = RZ_MIN(M68K_LONGEST_INSTRUCTION, len);
memcpy(mybuf, buf, mylen);
if (len > M68K_LONGEST_INSTRUCTION) {
len = M68K_LONGEST_INSTRUCTION;
}
n = cs_disasm(cd, mybuf, mylen, a->pc, 1, &insn);
n = cs_disasm(ctx->handle, buf, len, a->pc, 1, &insn);
if (n < 1) {
ret = -1;
goto beach;
@ -101,55 +91,30 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
ret = -1;
goto beach;
}
if (a->features && *a->features) {
if (!check_features(a, insn)) {
if (op) {
op->size = insn->size;
buf_asm = "illegal";
}
}
}
if (op && !op->size) {
op->size = insn->size;
buf_asm = sdb_fmt("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
buf_asm = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
}
if (op && buf_asm) {
char *p = rz_str_replace(strdup(buf_asm), "$", "0x", true);
if (p) {
rz_str_replace_char(p, '#', 0);
rz_asm_op_set_asm(op, p);
free(p);
buf_asm = rz_str_replace(buf_asm, "$", "0x", true);
if (buf_asm) {
rz_str_replace_char(buf_asm, '#', 0);
rz_asm_op_set_asm(op, buf_asm);
}
}
cs_free(insn, n);
beach:
// cs_close (&cd);
if (op && buf_asm) {
if (!strncmp(buf_asm, "dc.w", 4)) {
rz_asm_op_set_asm(op, "invalid");
}
return op->size;
ret = op->size;
}
free(buf_asm);
return ret;
}
static bool m68k_init(void **user) {
M68kContext *ctx = RZ_NEW0(M68kContext);
rz_return_val_if_fail(ctx, false);
ctx->omode = -1;
ctx->obits = 32;
*user = ctx;
return true;
}
static bool m68k_fini(void *p) {
M68kContext *ctx = (M68kContext *)p;
if (ctx) {
RZ_FREE(ctx);
}
return true;
}
RzAsmPlugin rz_asm_plugin_m68k_cs = {
.name = "m68k",
.desc = "Capstone M68K disassembler",
@ -160,15 +125,10 @@ RzAsmPlugin rz_asm_plugin_m68k_cs = {
.endian = RZ_SYS_ENDIAN_BIG,
.init = m68k_init,
.fini = m68k_fini,
.disassemble = &disassemble,
.mnemonics = &mnemonics,
.disassemble = &m68k_disassemble,
.mnemonics = &m68k_mnemonics,
};
static bool check_features(RzAsm *a, cs_insn *insn) {
/* TODO: Implement support for m68k */
return true;
}
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_ASM,

View file

@ -3,14 +3,15 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
#include "cs_helper.h"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(mips);
RZ_IPI int mips_assemble(const char *str, ut64 pc, ut8 *out);
static csh cd = 0;
#include "cs_mnemonics.c"
static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
cs_insn *insn;
int mode, n, ret = -1;
mode = (a->big_endian) ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN;
@ -31,27 +32,32 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
mode |= (a->bits == 64) ? CS_MODE_MIPS64 : CS_MODE_MIPS32;
memset(op, 0, sizeof(RzAsmOp));
op->size = 4;
if (cd != 0) {
cs_close(&cd);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->handle = 0;
ctx->omode = -1;
}
ret = cs_open(CS_ARCH_MIPS, mode, &cd);
if (ret) {
goto fin;
if (!ctx->handle) {
ret = cs_open(CS_ARCH_MIPS, mode, &ctx->handle);
if (ret) {
goto fin;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
if (a->syntax == RZ_ASM_SYNTAX_REGNUM) {
cs_option(cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
} else {
cs_option(cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
n = cs_disasm(cd, (ut8 *)buf, len, a->pc, 1, &insn);
n = cs_disasm(ctx->handle, (ut8 *)buf, len, a->pc, 1, &insn);
if (n < 1) {
rz_asm_op_set_asm(op, "invalid");
op->size = 4;
goto beach;
goto fin;
}
if (insn->size < 1) {
goto beach;
goto fin;
}
op->size = insn->size;
char *str = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
@ -62,8 +68,6 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
free(str);
}
cs_free(insn, n);
beach:
// cs_close (&cd);
fin:
return op->size;
}
@ -91,8 +95,10 @@ RzAsmPlugin rz_asm_plugin_mips_cs = {
.cpus = "mips32/64,micro,r6,v3,v2",
.bits = 16 | 32 | 64,
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
.disassemble = &disassemble,
.mnemonics = mnemonics,
.init = mips_init,
.fini = mips_fini,
.disassemble = &mips_disassemble,
.mnemonics = mips_mnemonics,
.assemble = &assemble
};

View file

@ -12,21 +12,28 @@
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct msp430_cmd cmd;
int ret = msp430_decode_command(buf, len, &cmd);
if (ret > 0) {
if (cmd.operands[0]) {
rz_strbuf_set(&op->buf_asm, sdb_fmt("%s %s", cmd.instr, cmd.operands));
} else {
rz_strbuf_set(&op->buf_asm, sdb_fmt("%s", cmd.instr));
}
char *buf_asm = NULL;
if (ret < 1) {
rz_asm_op_set_asm(op, "invalid");
goto fail;
}
if (cmd.operands[0]) {
buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
} else {
buf_asm = strdup(cmd.instr);
}
if (a->syntax != RZ_ASM_SYNTAX_ATT) {
char *ba = (char *)rz_strbuf_get(&op->buf_asm);
rz_str_replace_ch(ba, '#', 0, 1);
// rz_str_replace_ch (ba, "$", "$$", 1);
rz_str_replace_ch(ba, '&', 0, 1);
rz_str_replace_ch(ba, '%', 0, 1);
rz_str_replace_ch(buf_asm, '#', 0, 1);
// rz_str_replace_ch (buf_asm, "$", "$$", 1);
rz_str_replace_ch(buf_asm, '&', 0, 1);
rz_str_replace_ch(buf_asm, '%', 0, 1);
}
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
fail:
return op->size = ret;
}

View file

@ -42,70 +42,69 @@ static int insn_to_str(RzAsm *a, char **line, insn_t *descr, insn_extra_t *extra
if (!name || !type_descr->format) {
/* this should not happen, give up */
*line = sdb_fmt("invalid");
return 4;
}
switch (type) {
case INSN_X:
*line = sdb_fmt(type_descr->format, name);
*line = rz_str_newf(type_descr->format, name);
break;
case INSN_N:
*line = sdb_fmt(type_descr->format, name,
*line = rz_str_newf(type_descr->format, name,
(sign_extend(o.n, get_operand_mask(type_descr, INSN_OPER_N)) << 2) +
a->pc);
break;
case INSN_K:
*line = sdb_fmt(type_descr->format, name, o.k);
*line = rz_str_newf(type_descr->format, name, o.k);
break;
case INSN_DK:
*line = sdb_fmt(type_descr->format, name, o.rd, o.k);
*line = rz_str_newf(type_descr->format, name, o.rd, o.k);
break;
case INSN_DN:
*line = sdb_fmt(type_descr->format, name, o.rd, o.n << 13);
*line = rz_str_newf(type_descr->format, name, o.rd, o.n << 13);
break;
case INSN_B:
*line = sdb_fmt(type_descr->format, name, o.rb);
*line = rz_str_newf(type_descr->format, name, o.rb);
break;
case INSN_D:
*line = sdb_fmt(type_descr->format, name, o.rd);
*line = rz_str_newf(type_descr->format, name, o.rd);
break;
case INSN_AI:
*line = sdb_fmt(type_descr->format, name, o.ra, o.i);
*line = rz_str_newf(type_descr->format, name, o.ra, o.i);
break;
case INSN_DAI:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
*line = rz_str_newf(type_descr->format, name, o.rd, o.ra, o.i);
break;
case INSN_DAK:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
*line = rz_str_newf(type_descr->format, name, o.rd, o.ra, o.i);
break;
case INSN_DAL:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.l);
*line = rz_str_newf(type_descr->format, name, o.rd, o.ra, o.l);
break;
case INSN_DA:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra);
*line = rz_str_newf(type_descr->format, name, o.rd, o.ra);
break;
case INSN_DAB:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.rb);
*line = rz_str_newf(type_descr->format, name, o.rd, o.ra, o.rb);
break;
case INSN_AB:
*line = sdb_fmt(type_descr->format, name, o.ra, o.rb);
*line = rz_str_newf(type_descr->format, name, o.ra, o.rb);
break;
case INSN_IABI:
*line = sdb_fmt(type_descr->format, name,
*line = rz_str_newf(type_descr->format, name,
o.ra, o.rb, (o.k1 << 11) | o.k2);
break;
case INSN_KABK:
*line = sdb_fmt(type_descr->format, name,
*line = rz_str_newf(type_descr->format, name,
o.ra, o.rb, (o.k1 << 11) | o.k2);
break;
default:
*line = sdb_fmt("invalid");
break;
}
return 4;
}
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
static int or1k_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
ut32 insn, opcode;
ut8 opcode_idx;
char *line = NULL;
@ -115,8 +114,7 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
op->size = -1;
if (len < 4) {
line = sdb_fmt("invalid");
rz_strbuf_set(&op->buf_asm, line);
rz_strbuf_set(&op->buf_asm, "invalid");
return op->size;
}
@ -128,16 +126,14 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
/* make sure instruction descriptor table is not overflowed */
if (opcode_idx >= insns_count) {
line = sdb_fmt("invalid");
rz_strbuf_set(&op->buf_asm, line);
rz_strbuf_set(&op->buf_asm, "invalid");
return op->size;
}
/* if instruction is marked as invalid finish processing now */
insn_descr = &or1k_insns[opcode_idx];
if (insn_descr->type == INSN_INVAL) {
line = sdb_fmt("invalid");
rz_strbuf_set(&op->buf_asm, line);
rz_strbuf_set(&op->buf_asm, "invalid");
return op->size;
}
@ -146,14 +142,16 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
if (!insn_descr->name && insn_descr->extra) {
if ((extra_descr = find_extra_descriptor(insn_descr->extra, insn)) != NULL) {
insn_to_str(a, &line, insn_descr, extra_descr, insn);
} else {
line = "invalid";
}
rz_strbuf_set(&op->buf_asm, line);
} else {
/* otherwise basic descriptor is enough */
insn_to_str(a, &line, insn_descr, NULL, insn);
}
if (line) {
rz_strbuf_set(&op->buf_asm, line);
free(line);
} else {
rz_strbuf_set(&op->buf_asm, "invalid");
}
return op->size;
}
@ -165,7 +163,7 @@ RzAsmPlugin rz_asm_plugin_or1k = {
.arch = "or1k",
.bits = 32,
.endian = RZ_SYS_ENDIAN_BIG,
.disassemble = &disassemble,
.disassemble = &or1k_disassemble,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,19 +3,12 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
#include "../arch/ppc/libvle/vle.h"
#include "../arch/ppc/libps/libps.h"
static csh handle = 0;
#include "cs_helper.h"
static bool the_end(void *p) {
if (handle) {
cs_close(&handle);
handle = 0;
}
return true;
}
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(ppc);
static int decompile_vle(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
vle_t *instr = 0;
@ -54,17 +47,11 @@ static int decompile_ps(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
return op->size;
}
typedef struct {
int omode;
int obits;
} PpcContext;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
PpcContext *ctx = (PpcContext *)a->plugin_data;
int omode = ctx->omode;
int obits = ctx->obits;
int n, ret, mode;
static int ppc_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
int n, ret;
ut64 off = a->pc;
cs_mode mode = 0;
cs_insn *insn;
if (a->cpu && strncmp(a->cpu, "vle", 3) == 0) {
// vle is big-endian only
@ -101,26 +88,29 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
mode |= CS_MODE_QPX;
}
if (mode != omode || a->bits != obits) {
cs_close(&handle);
handle = 0;
omode = mode;
obits = a->bits;
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
if (handle == 0) {
ret = cs_open(CS_ARCH_PPC, mode, &handle);
if (ret != CS_ERR_OK) {
if (!ctx->handle) {
ret = cs_open(CS_ARCH_PPC, mode, &ctx->handle);
if (ret) {
return -1;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
op->size = 4;
cs_option(handle, CS_OPT_DETAIL, CS_OPT_OFF);
n = cs_disasm(handle, (const ut8 *)buf, len, off, 1, &insn);
n = cs_disasm(ctx->handle, (const ut8 *)buf, len, off, 1, &insn);
op->size = 4;
if (n > 0 && insn->size > 0) {
const char *opstr = sdb_fmt("%s%s%s", insn->mnemonic,
char *opstr = rz_str_newf("%s%s%s", insn->mnemonic,
insn->op_str[0] ? " " : "", insn->op_str);
rz_asm_op_set_asm(op, opstr);
if (opstr) {
rz_asm_op_set_asm(op, opstr);
free(opstr);
}
cs_free(insn, n);
return op->size;
}
@ -130,15 +120,6 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
return op->size;
}
static bool ppc_cs_init(void **user) {
PpcContext *ctx = RZ_NEW0(PpcContext);
rz_return_val_if_fail(ctx, false);
ctx->omode = -1;
ctx->obits = -1;
*user = ctx;
return true;
}
RzAsmPlugin rz_asm_plugin_ppc_cs = {
.name = "ppc",
.desc = "Capstone PowerPC disassembler",
@ -148,9 +129,10 @@ RzAsmPlugin rz_asm_plugin_ppc_cs = {
.cpus = "ppc,vle,ps,qpx",
.bits = 32 | 64,
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
.init = ppc_cs_init,
.fini = the_end,
.disassemble = &disassemble,
.init = ppc_init,
.fini = ppc_fini,
.disassemble = &ppc_disassemble,
.mnemonics = ppc_mnemonics,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -9,19 +9,22 @@
#include <propeller_disas.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
static int propeller_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
rz_return_val_if_fail(a && op && buf && len >= 4, -1);
const char *buf_asm;
char *buf_asm;
struct propeller_cmd cmd;
int ret = propeller_decode_command(buf, &cmd);
if (cmd.prefix[0] && cmd.operands[0]) {
buf_asm = sdb_fmt("%s %s %s", cmd.prefix, cmd.instr, cmd.operands);
buf_asm = rz_str_newf("%s %s %s", cmd.prefix, cmd.instr, cmd.operands);
} else if (cmd.operands[0]) {
buf_asm = sdb_fmt("%s %s", cmd.instr, cmd.operands);
buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
} else {
buf_asm = sdb_fmt("%s", cmd.instr);
buf_asm = strdup(cmd.instr);
}
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
rz_asm_op_set_asm(op, buf_asm);
op->size = 4;
return ret;
}
@ -33,7 +36,7 @@ RzAsmPlugin rz_asm_plugin_propeller = {
.arch = "propeller",
.bits = 32,
.endian = RZ_SYS_ENDIAN_BIG,
.disassemble = &disassemble
.disassemble = &propeller_disassemble
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,38 +3,44 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
#include "cs_helper.h"
static csh cd = 0;
#include "cs_mnemonics.c"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(riscv);
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
static int riscv_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
int ret = -1;
cs_insn *insn;
int mode = (a->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32;
cs_mode mode = (a->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32;
op->size = 4;
if (cd != 0) {
cs_close(&cd);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
int ret = cs_open(CS_ARCH_RISCV, mode, &cd);
if (ret) {
goto fin;
if (!ctx->handle) {
ret = cs_open(CS_ARCH_RISCV, mode, &ctx->handle);
if (ret) {
goto fin;
}
ctx->omode = mode;
// cs_option (ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
#if 0
if (a->syntax == RZ_ASM_SYNTAX_REGNUM) {
cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
cs_option (ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
} else {
cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
cs_option (ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
}
cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
#endif
int n = cs_disasm(cd, (ut8 *)buf, len, a->pc, 1, &insn);
int n = cs_disasm(ctx->handle, (ut8 *)buf, len, a->pc, 1, &insn);
if (n < 1) {
rz_asm_op_set_asm(op, "invalid");
op->size = 2;
goto beach;
goto fin;
}
if (insn->size < 1) {
goto beach;
goto fin;
}
op->size = insn->size;
char *str = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
@ -45,8 +51,6 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
free(str);
}
cs_free(insn, n);
beach:
// cs_close (&cd);
fin:
return op->size;
}
@ -59,8 +63,10 @@ RzAsmPlugin rz_asm_plugin_riscv_cs = {
.cpus = "",
.bits = 32 | 64,
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
.disassemble = &disassemble,
.mnemonics = mnemonics,
.init = riscv_init,
.fini = riscv_fini,
.disassemble = &riscv_disassemble,
.mnemonics = riscv_mnemonics,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -3,11 +3,13 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
static csh cd = 0;
#include "cs_mnemonics.c"
#include "cs_helper.h"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(sparc);
static int sparc_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
cs_insn *insn;
int n = -1, ret = -1;
int mode = CS_MODE_BIG_ENDIAN;
@ -20,41 +22,46 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
memset(op, 0, sizeof(RzAsmOp));
op->size = 4;
}
if (cd != 0) {
cs_close(&cd);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
ret = cs_open(CS_ARCH_SPARC, mode, &cd);
if (ret) {
goto fin;
if (!ctx->handle) {
ret = cs_open(CS_ARCH_SPARC, mode, &ctx->handle);
if (ret) {
goto fin;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
if (!op) {
return 0;
}
if (a->big_endian) {
n = cs_disasm(cd, buf, len, a->pc, 1, &insn);
n = cs_disasm(ctx->handle, buf, len, a->pc, 1, &insn);
}
if (n < 1) {
rz_asm_op_set_asm(op, "invalid");
op->size = 4;
ret = -1;
goto beach;
goto fin;
} else {
ret = 4;
}
if (insn->size < 1) {
goto beach;
goto fin;
}
op->size = insn->size;
char *buf_asm = sdb_fmt("%s%s%s",
char *buf_asm = rz_str_newf("%s%s%s",
insn->mnemonic, insn->op_str[0] ? " " : "",
insn->op_str);
rz_str_replace_char(buf_asm, '%', 0);
rz_asm_op_set_asm(op, buf_asm);
// TODO: remove the '$'<registername> in the string
if (buf_asm) {
rz_str_replace_char(buf_asm, '%', 0);
// TODO: remove the '$'<registername> in the string
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
cs_free(insn, n);
beach:
// cs_close (&cd);
fin:
return ret;
}
@ -67,8 +74,10 @@ RzAsmPlugin rz_asm_plugin_sparc_cs = {
.cpus = "v9",
.bits = 32 | 64,
.endian = RZ_SYS_ENDIAN_BIG | RZ_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble,
.mnemonics = mnemonics
.init = sparc_init,
.fini = sparc_fini,
.disassemble = &sparc_disassemble,
.mnemonics = sparc_mnemonics
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -5,69 +5,52 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
static csh cd = 0;
#include "cs_helper.h"
typedef struct {
int omode;
} SyszContext;
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(sysz);
static bool init(void **user) {
SyszContext *ctx = RZ_NEW0(SyszContext);
rz_return_val_if_fail(ctx, false);
ctx->omode = 0;
*user = ctx;
return true;
}
static bool the_end(void *p) {
SyszContext *ctx = (SyszContext *)p;
if (cd) {
cs_close(&cd);
cd = 0;
}
if (ctx) {
RZ_FREE(ctx);
}
return true;
}
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
SyszContext *ctx = (SyszContext *)a->plugin_data;
int omode = ctx->omode;
int mode, n, ret;
static int sysz_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
int n, ret;
ut64 off = a->pc;
cs_insn *insn = NULL;
mode = CS_MODE_BIG_ENDIAN;
if (cd && mode != omode) {
cs_close(&cd);
cd = 0;
}
cs_mode mode = CS_MODE_BIG_ENDIAN;
op->size = 0;
omode = mode;
if (cd == 0) {
ret = cs_open(CS_ARCH_SYSZ, mode, &cd);
if (ret) {
return 0;
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn);
if (!ctx->handle) {
ret = cs_open(CS_ARCH_SYSZ, mode, &ctx->handle);
if (ret) {
return -1;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
n = cs_disasm(ctx->handle, (const ut8 *)buf, len, off, 1, &insn);
if (n > 0) {
if (insn->size > 0) {
op->size = insn->size;
char *buf_asm = sdb_fmt("%s%s%s",
char *buf_asm = rz_str_newf("%s%s%s",
insn->mnemonic, insn->op_str[0] ? " " : "",
insn->op_str);
char *ptrstr = strstr(buf_asm, "ptr ");
if (ptrstr) {
memmove(ptrstr, ptrstr + 4, strlen(ptrstr + 4) + 1);
if (buf_asm) {
char *ptrstr = strstr(buf_asm, "ptr ");
if (ptrstr) {
memmove(ptrstr, ptrstr + 4, strlen(ptrstr + 4) + 1);
}
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
rz_asm_op_set_asm(op, buf_asm);
}
cs_free(insn, n);
} else {
rz_asm_op_set_asm(op, "invalid");
return -1;
}
return op->size;
}
@ -79,9 +62,10 @@ RzAsmPlugin rz_asm_plugin_sysz = {
.arch = "sysz",
.bits = 32 | 64,
.endian = RZ_SYS_ENDIAN_BIG,
.init = init,
.fini = the_end,
.disassemble = &disassemble,
.init = sysz_init,
.fini = sysz_fini,
.disassemble = &sysz_disassemble,
.mnemonics = sysz_mnemonics,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -31,19 +31,21 @@ static int tms320c64x_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len
cs_insn *insn;
int n = -1, ret = -1;
int mode = 0;
if (op) {
memset(op, 0, sizeof(RzAsmOp));
op->size = 4;
}
if (ctx->cd != 0) {
cs_close(&ctx->cd);
ctx->cd = 0;
}
ret = cs_open(CS_ARCH_TMS320C64X, mode, &ctx->cd);
if (ret) {
goto fin;
if (!ctx->cd) {
ret = cs_open(CS_ARCH_TMS320C64X, 0, &ctx->cd);
if (ret) {
goto fin;
}
cs_option(ctx->cd, CS_OPT_DETAIL, CS_OPT_OFF);
}
cs_option(ctx->cd, CS_OPT_DETAIL, CS_OPT_OFF);
if (!op) {
return 0;
}
@ -52,21 +54,22 @@ static int tms320c64x_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len
rz_asm_op_set_asm(op, "invalid");
op->size = 4;
ret = -1;
goto beach;
goto fin;
} else {
ret = 4;
}
if (insn->size < 1) {
goto beach;
goto fin;
}
op->size = insn->size;
char *buf_asm = sdb_fmt("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
rz_str_replace_char(buf_asm, '%', 0);
rz_str_case(buf_asm, false);
rz_asm_op_set_asm(op, buf_asm);
char *buf_asm = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
if (buf_asm) {
rz_str_replace_char(buf_asm, '%', 0);
rz_str_case(buf_asm, false);
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
cs_free(insn, n);
beach:
// cs_close (&ctx->cd);
fin:
return ret;
}

View file

@ -4,8 +4,6 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
static csh cd = 0;
#include "cs_mnemonics.c"
#ifdef CAPSTONE_TMS320C64X_H
#define CAPSTONE_HAS_TMS320C64X 1
@ -15,45 +13,55 @@ static csh cd = 0;
#endif
#if CAPSTONE_HAS_TMS320C64X
#include "cs_helper.h"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(tms320c64x);
static int tms320c64x_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
cs_insn *insn;
int n = -1, ret = -1;
int mode = 0;
if (op) {
memset(op, 0, sizeof(RzAsmOp));
op->size = 4;
}
if (cd != 0) {
cs_close(&cd);
if (ctx->omode != 0) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
ret = cs_open(CS_ARCH_TMS320C64X, mode, &cd);
if (ret) {
goto fin;
if (!ctx->handle) {
ret = cs_open(CS_ARCH_TMS320C64X, 0, &ctx->handle);
if (ret) {
goto fin;
}
ctx->omode = 0;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
if (!op) {
return 0;
}
n = cs_disasm(cd, buf, len, a->pc, 1, &insn);
n = cs_disasm(ctx->handle, buf, len, a->pc, 1, &insn);
if (n < 1) {
rz_asm_op_set_asm(op, "invalid");
op->size = 4;
ret = -1;
goto beach;
goto fin;
} else {
ret = 4;
}
if (insn->size < 1) {
goto beach;
goto fin;
}
op->size = insn->size;
rz_asm_op_set_asm(op, sdb_fmt("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str));
rz_str_replace_char(rz_strbuf_get(&op->buf_asm), '%', 0);
rz_str_case(rz_strbuf_get(&op->buf_asm), false);
char *buf_asm = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
if (buf_asm) {
rz_str_replace_char(buf_asm, '%', 0);
rz_str_case(buf_asm, false);
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
cs_free(insn, n);
beach:
// cs_close (&cd);
fin:
return ret;
}
@ -65,8 +73,10 @@ RzAsmPlugin rz_asm_plugin_tms320c64x = {
.arch = "tms320c64x",
.bits = 32,
.endian = RZ_SYS_ENDIAN_BIG | RZ_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble,
.mnemonics = mnemonics
.init = tms320c64x_init,
.fini = tms320c64x_fini,
.disassemble = &tms320c64x_disassemble,
.mnemonics = tms320c64x_mnemonics,
};
#else
@ -78,7 +88,6 @@ RzAsmPlugin rz_asm_plugin_tms320c64x = {
.arch = "tms320c64x",
.bits = 32,
.endian = RZ_SYS_ENDIAN_LITTLE,
.mnemonics = mnemonics
};
#endif

View file

@ -9,7 +9,7 @@
#include "../arch/v810/v810_disas.h"
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
static int v810_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct v810_cmd cmd = {
.instr = "",
.operands = ""
@ -19,7 +19,11 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
}
int ret = v810_decode_command(buf, len, &cmd);
if (ret > 0) {
rz_asm_op_set_asm(op, sdb_fmt("%s %s", cmd.instr, cmd.operands));
char *buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
}
return op->size = ret;
}
@ -32,7 +36,7 @@ RzAsmPlugin rz_asm_plugin_v810 = {
.arch = "v810",
.bits = 32,
.endian = RZ_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble
.disassemble = &v810_disassemble
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -9,7 +9,7 @@
#include <v850_disas.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
static int v850_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
struct v850_cmd cmd = {
.addr = a->pc,
.instr = "",
@ -20,7 +20,13 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
}
int ret = v850_decode_command(buf, len, &cmd);
if (ret > 0) {
rz_asm_op_set_asm(op, sdb_fmt("%s %s", cmd.instr, cmd.operands));
char *buf_asm = rz_str_newf("%s %s", cmd.instr, cmd.operands);
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
} else {
rz_asm_op_set_asm(op, "invalid");
}
return op->size = ret;
}
@ -32,7 +38,7 @@ RzAsmPlugin rz_asm_plugin_v850 = {
.arch = "v850",
.bits = 32,
.endian = RZ_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble
.disassemble = &v850_disassemble
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -5,72 +5,60 @@
#include <rz_lib.h>
#include <capstone/capstone.h>
static csh cd = 0;
static int n = 0;
static bool check_features(RzAsm *a, cs_insn *insn);
static int check_features(RzAsm *a, cs_insn *insn);
#include "cs_helper.h"
#include "cs_mnemonics.c"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(x86);
#include "asm_x86_vm.c"
typedef struct {
int omode;
} X86Context;
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
X86Context *ctx = (X86Context *)a->plugin_data;
int omode = ctx->omode;
int mode, ret;
static int x86_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
int ret, n;
ut64 off = a->pc;
mode = (a->bits == 64) ? CS_MODE_64 : (a->bits == 32) ? CS_MODE_32
: (a->bits == 16) ? CS_MODE_16
: 0;
if (cd && mode != omode) {
cs_close(&cd);
cd = 0;
}
cs_mode mode = (a->bits == 64) ? CS_MODE_64 : (a->bits == 32) ? CS_MODE_32
: (a->bits == 16) ? CS_MODE_16
: 0;
if (op) {
op->size = 0;
}
omode = mode;
if (cd == 0) {
ret = cs_open(CS_ARCH_X86, mode, &cd);
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
if (!ctx->handle) {
ret = cs_open(CS_ARCH_X86, mode, &ctx->handle);
if (ret) {
return 0;
return -1;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_UNSIGNED, CS_OPT_ON);
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_ON);
}
if (a->features && *a->features) {
cs_option(cd, CS_OPT_DETAIL, CS_OPT_ON);
} else {
cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF);
}
// always unsigned immediates (kernel addresses)
// maybe rizin should have an option for this too?
cs_option(cd, CS_OPT_UNSIGNED, CS_OPT_ON);
if (a->syntax == RZ_ASM_SYNTAX_MASM) {
cs_option(cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM);
cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM);
} else if (a->syntax == RZ_ASM_SYNTAX_ATT) {
cs_option(cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
} else {
cs_option(cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
}
cs_option(cd, CS_OPT_DETAIL, CS_OPT_ON);
if (!op) {
return true;
}
op->size = 1;
cs_insn *insn = NULL;
n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn);
n = cs_disasm(ctx->handle, (const ut8 *)buf, len, off, 1, &insn);
if (op) {
op->size = 0;
}
if (a->features && *a->features) {
if (!check_features(a, insn)) {
op->size = insn->size;
rz_asm_op_set_asm(op, "illegal");
}
if (!check_features(a, insn)) {
op->size = insn->size;
rz_asm_op_set_asm(op, "illegal");
}
if (op->size == 0 && n > 0 && insn->size > 0) {
char *ptrstr;
@ -113,26 +101,6 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
return op->size;
}
static bool x86_cs_init(void **user) {
X86Context *ctx = RZ_NEW0(X86Context);
rz_return_val_if_fail(ctx, false);
ctx->omode = 0;
*user = ctx;
return true;
}
static bool the_end(void *p) {
X86Context *ctx = (X86Context *)p;
if (cd) {
cs_close(&cd);
cd = 0;
}
if (ctx) {
free(ctx);
}
return true;
}
RzAsmPlugin rz_asm_plugin_x86_cs = {
.name = "x86",
.desc = "Capstone X86 disassembler",
@ -142,20 +110,24 @@ RzAsmPlugin rz_asm_plugin_x86_cs = {
.arch = "x86",
.bits = 16 | 32 | 64,
.endian = RZ_SYS_ENDIAN_LITTLE,
.init = x86_cs_init,
.fini = the_end,
.mnemonics = mnemonics,
.disassemble = &disassemble,
.init = x86_init,
.fini = x86_fini,
.mnemonics = x86_mnemonics,
.disassemble = &x86_disassemble,
.features = "vm,3dnow,aes,adx,avx,avx2,avx512,bmi,bmi2,cmov,"
"f16c,fma,fma4,fsgsbase,hle,mmx,rtm,sha,sse1,sse2,"
"sse3,sse41,sse42,sse4a,ssse3,pclmul,xop"
};
static int check_features(RzAsm *a, cs_insn *insn) {
static bool check_features(RzAsm *a, cs_insn *insn) {
if (RZ_STR_ISEMPTY(a->features)) {
return true;
}
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
const char *name;
int i;
if (!insn || !insn->detail) {
return 1;
return true;
}
for (i = 0; i < insn->detail->groups_count; i++) {
int id = insn->detail->groups[i];
@ -168,15 +140,15 @@ static int check_features(RzAsm *a, cs_insn *insn) {
if (id == X86_GRP_MODE64) {
continue;
}
name = cs_group_name(cd, id);
name = cs_group_name(ctx->handle, id);
if (!name) {
return 1;
return true;
}
if (!strstr(a->features, name)) {
return 0;
return false;
}
}
return 1;
return true;
}
#ifndef RZ_PLUGIN_INCORE

View file

@ -29,84 +29,89 @@
#define VPCEXT2(y, x) ((y)[2] == (x))
void decompile_vm(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
const char *buf_asm = "invalid";
if (len > 3 && buf[0] == 0x0F && buf[1] == 0x3F && (VPCEXT2(buf, 0x01) || VPCEXT2(buf, 0x05) || VPCEXT2(buf, 0x07) || VPCEXT2(buf, 0x0D) || VPCEXT2(buf, 0x10))) {
char *buf_asm = NULL;
if (a->syntax == RZ_ASM_SYNTAX_ATT) {
buf_asm = sdb_fmt("vpcext $0x%x, $0x%x", buf[3], buf[2]);
buf_asm = rz_str_newf("vpcext $0x%x, $0x%x", buf[3], buf[2]);
} else {
buf_asm = sdb_fmt("vpcext %xh, %xh", buf[2], buf[3]);
buf_asm = rz_str_newf("vpcext %xh, %xh", buf[2], buf[3]);
}
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
op->size = 4;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x00) {
/* 0F C6 28 00 00 vmgetinfo */
buf_asm = "vmgetinfo";
rz_asm_op_set_asm(op, "vmgetinfo");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x01) {
/* 0F C6 28 00 01 vmsetinfo */
buf_asm = "vmsetinfo";
rz_asm_op_set_asm(op, "vmsetinfo");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x02) {
/* 0F C6 28 00 02 vmdxdsbl */
buf_asm = "vmdxdsbl";
rz_asm_op_set_asm(op, "vmdxdsbl");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x03) {
/* 0F C6 28 00 03 vmdxenbl */
buf_asm = "vmdxenbl";
rz_asm_op_set_asm(op, "vmdxenbl");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x00) {
/* 0F C6 28 01 00 vmcpuid */
buf_asm = "vmcpuid";
rz_asm_op_set_asm(op, "vmcpuid");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x01) {
/* 0F C6 28 01 01 vmhlt */
buf_asm = "vmhlt";
rz_asm_op_set_asm(op, "vmhlt");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x02) {
/* 0F C6 28 01 02 vmsplaf */
buf_asm = "vmsplaf";
rz_asm_op_set_asm(op, "vmsplaf");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x00) {
/* 0F C6 28 02 00 vmpushfd */
buf_asm = "vmpushfd";
rz_asm_op_set_asm(op, "vmpushfd");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x01) {
/* 0F C6 28 02 01 vmpopfd */
buf_asm = "vmpopfd";
rz_asm_op_set_asm(op, "vmpopfd");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x02) {
/* 0F C6 28 02 02 vmcli */
buf_asm = "vmcli";
rz_asm_op_set_asm(op, "vmcli");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x03) {
/* 0F C6 28 02 03 vmsti */
buf_asm = "vmsti";
rz_asm_op_set_asm(op, "vmsti");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x04) {
/* 0F C6 28 02 04 vmiretd */
buf_asm = "vmiretd";
rz_asm_op_set_asm(op, "vmiretd");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x00) {
/* 0F C6 28 03 00 vmsgdt */
buf_asm = "vmsgdt";
rz_asm_op_set_asm(op, "vmsgdt");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x01) {
/* 0F C6 28 03 01 vmsidt */
buf_asm = "vmsidt";
rz_asm_op_set_asm(op, "vmsidt");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x02) {
/* 0F C6 28 03 02 vmsldt */
buf_asm = "vmsldt";
rz_asm_op_set_asm(op, "vmsldt");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x03) {
/* 0F C6 28 03 03 vmstr */
buf_asm = "vmstr";
rz_asm_op_set_asm(op, "vmstr");
op->size = 5;
} else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x04 && buf[4] == 0x00) {
/* 0F C6 28 04 00 vmsdte */
buf_asm = "vmsdte";
rz_asm_op_set_asm(op, "vmsdte");
op->size = 5;
} else {
rz_asm_op_set_asm(op, "invalid");
}
rz_asm_op_set_asm(op, buf_asm);
}
#undef VPCEXT2

View file

@ -3,21 +3,33 @@
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
csh handle;
#include "cs_helper.h"
CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(xcore);
static int xcore_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data;
cs_insn *insn;
int mode, n, ret = -1;
mode = a->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN;
int n, ret = -1;
cs_mode mode = a->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN;
memset(op, 0, sizeof(RzAsmOp));
op->size = 4;
ret = cs_open(CS_ARCH_XCORE, mode, &handle);
if (ret) {
goto fin;
if (ctx->omode != mode) {
cs_close(&ctx->handle);
ctx->omode = -1;
}
cs_option(handle, CS_OPT_DETAIL, CS_OPT_OFF);
n = cs_disasm(handle, (ut8 *)buf, len, a->pc, 1, &insn);
if (!ctx->handle) {
ret = cs_open(CS_ARCH_XCORE, mode, &ctx->handle);
if (ret) {
goto fin;
}
ctx->omode = mode;
cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF);
}
n = cs_disasm(ctx->handle, (ut8 *)buf, len, a->pc, 1, &insn);
if (n < 1) {
rz_asm_op_set_asm(op, "invalid");
op->size = 4;
@ -29,11 +41,20 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
goto beach;
}
op->size = insn->size;
rz_asm_op_set_asm(op, sdb_fmt("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str));
if (insn->op_str[0]) {
char *buf_asm = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str);
if (buf_asm) {
rz_asm_op_set_asm(op, buf_asm);
free(buf_asm);
}
} else {
rz_asm_op_set_asm(op, insn->mnemonic);
}
// TODO: remove the '$'<registername> in the string
beach:
cs_free(insn, n);
cs_close(&handle);
fin:
return ret;
}
@ -46,7 +67,10 @@ RzAsmPlugin rz_asm_plugin_xcore_cs = {
.arch = "xcore",
.bits = 32,
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
.disassemble = &disassemble,
.init = &xcore_init,
.fini = &xcore_fini,
.disassemble = &xcore_disassemble,
.mnemonics = &xcore_mnemonics,
};
#ifndef RZ_PLUGIN_INCORE

84
librz/asm/p/cs_helper.h Normal file
View file

@ -0,0 +1,84 @@
// SPDX-FileCopyrightText: 2024 deroad <wargio@libero.it>
// SPDX-FileCopyrightText: 2016-2018 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_util.h>
#include <capstone/capstone.h>
typedef struct {
cs_mode omode;
int obits;
csh handle;
} CapstoneContext;
#define CAPSTONE_PLUGIN_INIT(name) \
static bool name##_init(void **user) { \
CapstoneContext *ctx = RZ_NEW0(CapstoneContext); \
if (!ctx) { \
return false; \
} \
ctx->omode = -1; \
ctx->handle = 0; \
*user = ctx; \
return true; \
}
#define CAPSTONE_PLUGIN_FINI(name) \
static bool name##_fini(void *p) { \
if (!p) { \
return true; \
} \
CapstoneContext *ctx = (CapstoneContext *)p; \
\
if (ctx->handle) { \
cs_close(&ctx->handle); \
} \
free(ctx); \
return true; \
}
#define CAPSTONE_PLUGIN_MNEMONICS(name) \
static char *name##_mnemonics(RzAsm *a, int id, bool json) { \
if (!a->plugin_data) { \
return NULL; \
} \
CapstoneContext *ctx = (CapstoneContext *)a->plugin_data; \
int i; \
a->cur->disassemble(a, NULL, NULL, -1); \
if (id != -1) { \
const char *name = cs_insn_name(ctx->handle, id); \
if (json) { \
return name ? rz_str_newf("[\"%s\"]\n", name) : NULL; \
} \
return name ? strdup(name) : NULL; \
} \
RzStrBuf *buf = rz_strbuf_new(""); \
if (json) { \
rz_strbuf_append(buf, "["); \
} \
for (i = 1;; i++) { \
const char *op = cs_insn_name(ctx->handle, i); \
if (!op) { \
break; \
} \
if (json) { \
rz_strbuf_append(buf, "\""); \
} \
rz_strbuf_append(buf, op); \
if (json) { \
if (cs_insn_name(ctx->handle, i + 1)) { \
rz_strbuf_append(buf, "\","); \
} else { \
rz_strbuf_append(buf, "\"]\n"); \
} \
} else { \
rz_strbuf_append(buf, "\n"); \
} \
} \
return rz_strbuf_drain(buf); \
}
#define CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(name) \
CAPSTONE_PLUGIN_INIT(name) \
CAPSTONE_PLUGIN_FINI(name) \
CAPSTONE_PLUGIN_MNEMONICS(name)

View file

@ -1,38 +0,0 @@
// SPDX-FileCopyrightText: 2016-2018 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
static char *mnemonics(RzAsm *a, int id, bool json) {
int i;
a->cur->disassemble(a, NULL, NULL, -1);
if (id != -1) {
const char *name = cs_insn_name(cd, id);
if (json) {
return name ? rz_str_newf("[\"%s\"]\n", name) : NULL;
}
return name ? strdup(name) : NULL;
}
RzStrBuf *buf = rz_strbuf_new("");
if (json) {
rz_strbuf_append(buf, "[");
}
for (i = 1;; i++) {
const char *op = cs_insn_name(cd, i);
if (!op) {
break;
}
if (json) {
rz_strbuf_append(buf, "\"");
}
rz_strbuf_append(buf, op);
if (json) {
if (cs_insn_name(cd, i + 1)) {
rz_strbuf_append(buf, "\",");
} else {
rz_strbuf_append(buf, "\"]\n");
}
} else {
rz_strbuf_append(buf, "\n");
}
}
return rz_strbuf_drain(buf);
}