Skip to content

Commit

Permalink
context-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
HN026 committed Jan 15, 2024
1 parent 4a55ad7 commit a9d2ac9
Show file tree
Hide file tree
Showing 10 changed files with 303 additions and 100 deletions.
48 changes: 35 additions & 13 deletions librz/asm/p/asm_arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_in
DECLARE_GENERIC_PRINT_ADDRESS_FUNC()
DECLARE_GENERIC_FPRINTF_FUNC()

typedef struct {
struct disassemble_info disasm_obj;
} ArcContext;

static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
ArcContext *ctx = (ArcContext *)a->plugin_data;
if (len < 2) {
return -1;
}
Expand All @@ -57,35 +62,52 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
memcpy(bytes, buf, len); // TODO handle compact
buf_len = len;
/* prepare disassembler */
memset(&a->disasm_obj, '\0', sizeof(struct disassemble_info));
a->disasm_obj.buffer = bytes;
a->disasm_obj.buffer_length = len;
a->disasm_obj.read_memory_func = &arc_buffer_read_memory;
a->disasm_obj.symbol_at_address_func = &symbol_at_address;
a->disasm_obj.memory_error_func = &memory_error_func;
a->disasm_obj.print_address_func = &generic_print_address_func;
a->disasm_obj.endian = !a->big_endian;
a->disasm_obj.fprintf_func = &generic_fprintf_func;
a->disasm_obj.stream = stdout;
a->disasm_obj.mach = 0;
memset(&ctx->disasm_obj, '\0', sizeof(struct disassemble_info));
ctx->disasm_obj.buffer = bytes;
ctx->disasm_obj.buffer_length = len;
ctx->disasm_obj.read_memory_func = &arc_buffer_read_memory;
ctx->disasm_obj.symbol_at_address_func = &symbol_at_address;
ctx->disasm_obj.memory_error_func = &memory_error_func;
ctx->disasm_obj.print_address_func = &generic_print_address_func;
ctx->disasm_obj.endian = !a->big_endian;
ctx->disasm_obj.fprintf_func = &generic_fprintf_func;
ctx->disasm_obj.stream = stdout;
ctx->disasm_obj.mach = 0;
rz_strbuf_set(&op->buf_asm, "");
if (a->bits == 16) {
op->size = ARCompact_decodeInstr((bfd_vma)Offset, &a->disasm_obj);
op->size = ARCompact_decodeInstr((bfd_vma)Offset, &ctx->disasm_obj);
} else {
op->size = ARCTangent_decodeInstr((bfd_vma)Offset, &a->disasm_obj);
op->size = ARCTangent_decodeInstr((bfd_vma)Offset, &ctx->disasm_obj);
}
if (op->size == -1) {
rz_strbuf_set(&op->buf_asm, "(data)");
}
return op->size;
}

static bool init(void **user) {
ArcContext *ctx = RZ_NEW0(ArcContext);
rz_return_val_if_fail(ctx, false);
*user = ctx;
return true;
}

static bool the_end(void *p) {
ArcContext *ctx = (ArcContext *)p;
if (ctx) {
RZ_FREE(ctx);
}
return true;
}

RzAsmPlugin rz_asm_plugin_arc = {
.name = "arc",
.arch = "arc",
.bits = 16 | 32,
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
.desc = "Argonaut RISC Core",
.init = init,
.fini = the_end,
.disassemble = &disassemble,
.license = "GPL3"
};
Expand Down
41 changes: 33 additions & 8 deletions librz/asm/p/asm_bf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,50 @@
#include <rz_analysis.h>
#include <rz_asm.h>

typedef struct {
RzPVector /*<RzAsmTokenPattern *>*/ *token_patterns;
} BfContext;

static RZ_OWN RzPVector /*<RzAsmTokenPattern *>*/ *get_token_patterns(RzAsm *a) {
if (a->token_patterns) {
return a->token_patterns;
BfContext *ctx = (BfContext *)a->plugin_data;
RzPVector *pvec = ctx->token_patterns;
if (pvec) {
return pvec;
}

a->token_patterns = rz_pvector_new(rz_asm_token_pattern_free);
pvec = rz_pvector_new(rz_asm_token_pattern_free);

// Patterns get added here.
// Mnemonic pattern
RzAsmTokenPattern *pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_MNEMONIC;
pat->pattern = strdup(
"^(while|inc|dec|out|in|trap|nop|invalid|loop)");
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

// ptr pattern
pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_REGISTER;
pat->pattern = strdup(
"(ptr)");
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

// reference pattern
pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_OPERATOR;
pat->pattern = strdup(
"(\\[)|(\\])" // Matches a single bracket
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

// Separator pattern
pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_SEPARATOR;
pat->pattern = strdup(
"([[:blank:]]+)");
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

return a->token_patterns;
return pvec;
}

static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
Expand Down Expand Up @@ -163,6 +169,23 @@ static int assemble(RzAsm *a, RzAsmOp *op, const char *buf) {
return n;
}

static bool bf_init(void **user) {
BfContext *ctx = RZ_NEW0(BfContext);
rz_return_val_if_fail(ctx, false);
ctx->token_patterns = NULL;
*user = ctx;
return true;
}

static bool bf_fini(void *user) {
BfContext *ctx = (BfContext *)user;
if (ctx) {
rz_pvector_free(ctx->token_patterns);
RZ_FREE(ctx);
}
return true;
}

RzAsmPlugin rz_asm_plugin_bf = {
.name = "bf",
.author = "pancake, nibble",
Expand All @@ -172,6 +195,8 @@ RzAsmPlugin rz_asm_plugin_bf = {
.bits = 16 | 32 | 64,
.endian = RZ_SYS_ENDIAN_NONE,
.desc = "Brainfuck",
.init = bf_init,
.fini = bf_fini,
.disassemble = &disassemble,
.assemble = &assemble
};
Expand Down
48 changes: 31 additions & 17 deletions librz/asm/p/asm_hexagon.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,95 +19,96 @@
#include "hexagon_insn.h"
#include "hexagon_arch.h"

static RZ_OWN RzPVector /*<RzAsmTokenPattern *>*/ *get_token_patterns(RzAsm *a) {
if (a->token_patterns) {
return a->token_patterns;
static RZ_OWN RzPVector /*<RzAsmTokenPattern *>*/ *get_token_patterns(HexState *state) {
RzPVector *pvec = state->token_patterns;
if (pvec) {
return pvec;
}

a->token_patterns = rz_pvector_new(rz_asm_token_pattern_free);
pvec = rz_pvector_new(rz_asm_token_pattern_free);

RzAsmTokenPattern *pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_META;
pat->pattern = strdup(
"(^[\\[\\?\\/\\|\\\\\\{])|(┌)|(│)|(└)|" // Packet prefix
"((∎)|[<\\}])([ :])(endloop[01]{1,2})" // Endloop markers
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_META;
pat->pattern = strdup(
"(#{1,2})|(\\}$)|" // Immediate prefix, Closing packet bracket
"\\.new|:n?t|:raw|<err>" // .new and jump hints
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_REGISTER;
pat->pattern = strdup(
"([CNPRMQVO][[:digit:]]{1,2}(:[[:digit:]]{1,2})?(in)?)" // Registers and double registers
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_REGISTER;
pat->pattern = strdup(
"GP|HTID|UGP|LR|FP|SP" // Other regs
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_NUMBER;
pat->pattern = strdup(
"(0x[[:digit:]abcdef]+)" // Hexadecimal numbers
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_MNEMONIC;
pat->pattern = strdup(
"([[:alpha:]]+[[:digit:]]+[[:alpha:]]*)" // Mnemonics with a decimal number in the name.
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_NUMBER;
pat->pattern = strdup(
"([[:digit:]]+)" // Decimal numbers
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_SEPARATOR;
pat->pattern = strdup(
"([[:blank:]]+)|" // Spaces and tabs
"([,;\\.\\(\\)\\{\\}:])" // Brackets and others
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_OPERATOR;
pat->pattern = strdup(
"(\\+)|(=)|(!)|(-)" // +,-,=,],[, ! (not the packet prefix)
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_OPERATOR;
pat->pattern = strdup(
"(\\])|(\\[|<{1,2}|>{1,2})" // +,-,=,],[, ! (not the packet prefix)
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

pat = RZ_NEW0(RzAsmTokenPattern);
pat->type = RZ_ASM_TOKEN_MNEMONIC;
pat->pattern = strdup(
"([[:alnum:]]+)|" // Alphanumeric mnemonics
"([[:alnum:]]+_[[:alnum:]]+)" // Menmonics with "_" e.g dealloc_return
);
rz_pvector_push(a->token_patterns, pat);
rz_pvector_push(pvec, pat);

return a->token_patterns;
return pvec;
}

/**
Expand Down Expand Up @@ -155,12 +156,24 @@ static bool hexagon_init(void **user) {
SETCB("plugins.hexagon.sdk", "false", &hex_cfg_set, "Print packet syntax in objdump style.");
SETCB("plugins.hexagon.reg.alias", "true", &hex_cfg_set, "Print the alias of registers (Alias from C0 = SA0).");

state->token_patterns = get_token_patterns(&state->rz_asm);
state->token_patterns = get_token_patterns(state);
rz_asm_compile_token_patterns(state->token_patterns);

return true;
}

static bool hexagon_fini(void *user) {
HexState *state = (HexState *)user;
rz_return_val_if_fail(state, false);

if (state->token_patterns) {
rz_pvector_free(state->token_patterns);
state->token_patterns = NULL;
}

return true;
}

RZ_API RZ_BORROW RzConfig *hexagon_get_config() {
HexState *state = hexagon_get_state();
rz_return_val_if_fail(state, NULL);
Expand Down Expand Up @@ -196,6 +209,7 @@ RzAsmPlugin rz_asm_plugin_hexagon = {
.bits = 32,
.desc = "Qualcomm Hexagon (QDSP6) V6",
.init = &hexagon_init,
.fini = hexagon_fini,
.disassemble = &disassemble,
.get_config = &hexagon_get_config,
};
Expand Down
24 changes: 21 additions & 3 deletions librz/asm/p/asm_m680x_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,43 @@ static int m680xmode(const char *str) {
return CS_MODE_M680X_6800;
}

typedef struct {
int omode;
} M680xContext;

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) {
a->omode = 0;
M680xContext *ctx = (M680xContext *)a->plugin_data;
int omode = ctx->omode;
int mode, n, ret;
ut64 off = a->pc;
cs_insn *insn = NULL;
mode = m680xmode(a->cpu);
if (cd && mode != a->omode) {
if (cd && mode != omode) {
cs_close(&cd);
cd = 0;
}
op->size = 0;
a->omode = mode;
omode = mode;
if (cd == 0) {
ret = cs_open(CS_ARCH_M680X, mode, &cd);
if (ret) {
Expand Down Expand Up @@ -92,6 +109,7 @@ RzAsmPlugin rz_asm_plugin_m680x_cs = {
.arch = "m680x",
.bits = 8 | 32,
.endian = RZ_SYS_ENDIAN_LITTLE,
.init = m680x_init,
.fini = the_end,
.disassemble = &disassemble,
};
Expand Down
Loading

0 comments on commit a9d2ac9

Please sign in to comment.