From 0b54b574322a73e8ee8c296ede3ec7e4effb3259 Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:02:23 +0800 Subject: [PATCH] Remove globals in RzAsm plugins (#4114) * Remove globals in RzAsm plugins * Fix breakage due small mistakes --- librz/asm/p/asm_arm_cs.c | 11 ++-- librz/asm/p/asm_chip8.c | 99 ++++++++++++++++--------------- librz/asm/p/asm_cr16.c | 12 ++-- librz/asm/p/asm_dalvik.c | 9 +-- librz/asm/p/asm_ebc.c | 13 +++-- librz/asm/p/asm_h8300.c | 6 +- librz/asm/p/asm_m680x_cs.c | 69 ++++++++-------------- librz/asm/p/asm_m68k_cs.c | 108 +++++++++++----------------------- librz/asm/p/asm_mips_cs.c | 44 ++++++++------ librz/asm/p/asm_msp430.c | 29 +++++---- librz/asm/p/asm_or1k.c | 56 +++++++++--------- librz/asm/p/asm_ppc_cs.c | 68 ++++++++-------------- librz/asm/p/asm_propeller.c | 17 +++--- librz/asm/p/asm_riscv_cs.c | 46 ++++++++------- librz/asm/p/asm_sparc_cs.c | 51 +++++++++------- librz/asm/p/asm_sysz.c | 82 +++++++++++--------------- librz/asm/p/asm_tms320.c | 29 ++++----- librz/asm/p/asm_tms320c64x.c | 51 +++++++++------- librz/asm/p/asm_v810.c | 10 +++- librz/asm/p/asm_v850.c | 12 +++- librz/asm/p/asm_x86_cs.c | 110 +++++++++++++---------------------- librz/asm/p/asm_x86_vm.c | 47 ++++++++------- librz/asm/p/asm_xcore_cs.c | 50 +++++++++++----- librz/asm/p/cs_helper.h | 84 ++++++++++++++++++++++++++ librz/asm/p/cs_mnemonics.c | 38 ------------ 25 files changed, 589 insertions(+), 562 deletions(-) create mode 100644 librz/asm/p/cs_helper.h delete mode 100644 librz/asm/p/cs_mnemonics.c diff --git a/librz/asm/p/asm_arm_cs.c b/librz/asm/p/asm_arm_cs.c index 9e7c84dc1be..dd231fe40f1 100644 --- a/librz/asm/p/asm_arm_cs.c +++ b/librz/asm/p/asm_arm_cs.c @@ -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: diff --git a/librz/asm/p/asm_chip8.c b/librz/asm/p/asm_chip8.c index c3ec881772b..cbe56fd2e2b 100644 --- a/librz/asm/p/asm_chip8.c +++ b/librz/asm/p/asm_chip8.c @@ -4,84 +4,89 @@ #include #include -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 diff --git a/librz/asm/p/asm_cr16.c b/librz/asm/p/asm_cr16.c index d58504c6561..8cafbd18f0c 100644 --- a/librz/asm/p/asm_cr16.c +++ b/librz/asm/p/asm_cr16.c @@ -8,10 +8,14 @@ #include #include -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 diff --git a/librz/asm/p/asm_dalvik.c b/librz/asm/p/asm_dalvik.c index 4ab3c8aeece..0721b8e52f0 100644 --- a/librz/asm/p/asm_dalvik.c +++ b/librz/asm/p/asm_dalvik.c @@ -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) { diff --git a/librz/asm/p/asm_ebc.c b/librz/asm/p/asm_ebc.c index 4b929403e25..deebcd2e579 100644 --- a/librz/asm/p/asm_ebc.c +++ b/librz/asm/p/asm_ebc.c @@ -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; } diff --git a/librz/asm/p/asm_h8300.c b/librz/asm/p/asm_h8300.c index b04fabd7a76..fea1572a55f 100644 --- a/librz/asm/p/asm_h8300.c +++ b/librz/asm/p/asm_h8300.c @@ -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; } diff --git a/librz/asm/p/asm_m680x_cs.c b/librz/asm/p/asm_m680x_cs.c index 2054a640bfa..b361bf0a4f0 100644 --- a/librz/asm/p/asm_m680x_cs.c +++ b/librz/asm/p/asm_m680x_cs.c @@ -3,11 +3,11 @@ #include #include -#include +#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 (ctx->omode != mode) { + cs_close(&ctx->handle); + ctx->omode = -1; + } + if (!ctx->handle) { + ret = cs_open(CS_ARCH_M680X, mode, &ctx->handle); if (ret) { - return 0; + return -1; } - cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF); + ctx->omode = mode; + cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF); } - n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn); + + 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 diff --git a/librz/asm/p/asm_m68k_cs.c b/librz/asm/p/asm_m68k_cs.c index bc3479810ff..15679ac889f 100644 --- a/librz/asm/p/asm_m68k_cs.c +++ b/librz/asm/p/asm_m68k_cs.c @@ -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, diff --git a/librz/asm/p/asm_mips_cs.c b/librz/asm/p/asm_mips_cs.c index 7753e752afc..0d9582dd396 100644 --- a/librz/asm/p/asm_mips_cs.c +++ b/librz/asm/p/asm_mips_cs.c @@ -3,14 +3,15 @@ #include #include -#include +#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 }; diff --git a/librz/asm/p/asm_msp430.c b/librz/asm/p/asm_msp430.c index 0b689a9d259..7bcf697feaf 100644 --- a/librz/asm/p/asm_msp430.c +++ b/librz/asm/p/asm_msp430.c @@ -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; } diff --git a/librz/asm/p/asm_or1k.c b/librz/asm/p/asm_or1k.c index 48c5587f33a..f7156bdcc1f 100644 --- a/librz/asm/p/asm_or1k.c +++ b/librz/asm/p/asm_or1k.c @@ -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 diff --git a/librz/asm/p/asm_ppc_cs.c b/librz/asm/p/asm_ppc_cs.c index da177ee58c8..7a68d431920 100644 --- a/librz/asm/p/asm_ppc_cs.c +++ b/librz/asm/p/asm_ppc_cs.c @@ -3,19 +3,12 @@ #include #include -#include #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 diff --git a/librz/asm/p/asm_propeller.c b/librz/asm/p/asm_propeller.c index 95106dd9fd0..ec89f8aac23 100644 --- a/librz/asm/p/asm_propeller.c +++ b/librz/asm/p/asm_propeller.c @@ -9,19 +9,22 @@ #include -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 diff --git a/librz/asm/p/asm_riscv_cs.c b/librz/asm/p/asm_riscv_cs.c index 735a9329998..1bd87f4cd14 100644 --- a/librz/asm/p/asm_riscv_cs.c +++ b/librz/asm/p/asm_riscv_cs.c @@ -3,38 +3,44 @@ #include #include -#include +#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 diff --git a/librz/asm/p/asm_sparc_cs.c b/librz/asm/p/asm_sparc_cs.c index 85d4ca1f0f5..7dc54730461 100644 --- a/librz/asm/p/asm_sparc_cs.c +++ b/librz/asm/p/asm_sparc_cs.c @@ -3,11 +3,13 @@ #include #include -#include -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 '$' in the string + if (buf_asm) { + rz_str_replace_char(buf_asm, '%', 0); + // TODO: remove the '$' 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 diff --git a/librz/asm/p/asm_sysz.c b/librz/asm/p/asm_sysz.c index 13bc53fac8f..0e7e3970d39 100644 --- a/librz/asm/p/asm_sysz.c +++ b/librz/asm/p/asm_sysz.c @@ -5,69 +5,52 @@ #include #include -#include -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 (ctx->omode != mode) { + cs_close(&ctx->handle); + ctx->omode = -1; + } + if (!ctx->handle) { + ret = cs_open(CS_ARCH_SYSZ, mode, &ctx->handle); if (ret) { - return 0; + return -1; } - cs_option(cd, CS_OPT_DETAIL, CS_OPT_OFF); + ctx->omode = mode; + cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF); } - n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn); + + 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 diff --git a/librz/asm/p/asm_tms320.c b/librz/asm/p/asm_tms320.c index 56536532277..403fd70a60c 100644 --- a/librz/asm/p/asm_tms320.c +++ b/librz/asm/p/asm_tms320.c @@ -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; } diff --git a/librz/asm/p/asm_tms320c64x.c b/librz/asm/p/asm_tms320c64x.c index 201f49dc92a..1c19ed04f17 100644 --- a/librz/asm/p/asm_tms320c64x.c +++ b/librz/asm/p/asm_tms320c64x.c @@ -4,8 +4,6 @@ #include #include #include -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 diff --git a/librz/asm/p/asm_v810.c b/librz/asm/p/asm_v810.c index 8fd66427f95..b543b3b24e6 100644 --- a/librz/asm/p/asm_v810.c +++ b/librz/asm/p/asm_v810.c @@ -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 diff --git a/librz/asm/p/asm_v850.c b/librz/asm/p/asm_v850.c index bb439064e9f..ecd47b4f843 100644 --- a/librz/asm/p/asm_v850.c +++ b/librz/asm/p/asm_v850.c @@ -9,7 +9,7 @@ #include -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 diff --git a/librz/asm/p/asm_x86_cs.c b/librz/asm/p/asm_x86_cs.c index 6396e54f20e..7ab82c4fefa 100644 --- a/librz/asm/p/asm_x86_cs.c +++ b/librz/asm/p/asm_x86_cs.c @@ -5,72 +5,60 @@ #include #include -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 diff --git a/librz/asm/p/asm_x86_vm.c b/librz/asm/p/asm_x86_vm.c index 5d4bdb99bb1..e10a9a5c508 100644 --- a/librz/asm/p/asm_x86_vm.c +++ b/librz/asm/p/asm_x86_vm.c @@ -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 diff --git a/librz/asm/p/asm_xcore_cs.c b/librz/asm/p/asm_xcore_cs.c index b1ebe1624c8..002934eda11 100644 --- a/librz/asm/p/asm_xcore_cs.c +++ b/librz/asm/p/asm_xcore_cs.c @@ -3,21 +3,33 @@ #include #include -#include -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; + } + 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); } - cs_option(handle, CS_OPT_DETAIL, CS_OPT_OFF); - n = cs_disasm(handle, (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; @@ -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 '$' 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 diff --git a/librz/asm/p/cs_helper.h b/librz/asm/p/cs_helper.h new file mode 100644 index 00000000000..c74296b5f15 --- /dev/null +++ b/librz/asm/p/cs_helper.h @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2024 deroad +// SPDX-FileCopyrightText: 2016-2018 pancake +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include + +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) diff --git a/librz/asm/p/cs_mnemonics.c b/librz/asm/p/cs_mnemonics.c deleted file mode 100644 index e42e68e8dbc..00000000000 --- a/librz/asm/p/cs_mnemonics.c +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: 2016-2018 pancake -// 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); -}