summaryrefslogtreecommitdiff
path: root/misc/radare2
diff options
context:
space:
mode:
Diffstat (limited to 'misc/radare2')
-rw-r--r--misc/radare2/Makefile30
-rw-r--r--misc/radare2/asm_fspec.c142
2 files changed, 172 insertions, 0 deletions
diff --git a/misc/radare2/Makefile b/misc/radare2/Makefile
new file mode 100644
index 0000000..aff2fdb
--- /dev/null
+++ b/misc/radare2/Makefile
@@ -0,0 +1,30 @@
+MAKEFLAGS += --no-builtin-rules
+R2_PLUGIN_PATH ?= $(shell r2 -H R2_USER_PLUGINS)
+
+# GCC 7: -Wstringop-overflow=, -Walloc-size-larger-than=, -Wduplicated-{branches,cond}
+WARNINGS := -Wall -Wextra -Wformat=2 -Wstrict-aliasing=3 -Wstrict-overflow=5 -Wstack-usage=12500 \
+ -Wfloat-equal -Wcast-align -Wpointer-arith -Wchar-subscripts -Warray-bounds=2
+
+override CFLAGS ?= -g
+override CFLAGS += -std=c11 $(WARNINGS)
+
+libs = asm_fspec.so
+all: $(libs)
+
+%.so:
+ $(LINK.c) -fPIC -shared $(filter %.c,$^) $(LDLIBS) -o $@
+
+asm_fspec.so: private CFLAGS += $(shell pkg-config --cflags r_anal)
+asm_fspec.so: private LDLIBS += $(shell pkg-config --libs-only-l r_anal)
+asm_fspec.so: asm_fspec.c
+
+install: $(libs)
+ install -Dm755 $^ -t "$(R2_PLUGIN_PATH)"
+
+uninstall:
+ $(RM) "$(R2_PLUGIN_PATH)"/asm_fspec.so
+
+clean:
+ $(RM) $(libs)
+
+.PHONY: all clean install uninstall
diff --git a/misc/radare2/asm_fspec.c b/misc/radare2/asm_fspec.c
new file mode 100644
index 0000000..fa7c1ad
--- /dev/null
+++ b/misc/radare2/asm_fspec.c
@@ -0,0 +1,142 @@
+/* radare - LGPL - Copyright 2018 - Jari Vetoniemi */
+
+#include <stdio.h>
+#include <string.h>
+#include <r_types.h>
+#include <r_util.h>
+#include <r_lib.h>
+#include <r_asm.h>
+
+enum fspec_instruction {
+ INS_VERSION,
+ INS_REG,
+ INS_PUSH,
+ INS_PUSHR,
+ INS_STORE,
+ INS_OP,
+ INS_QUEUE,
+ INS_IO,
+ INS_EXEC,
+ INS_CALL,
+ INS_JMP,
+ INS_JMPIF
+};
+
+enum fspec_operation {
+ OP_UNM,
+ OP_LNOT,
+ OP_BNOT,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_ADD,
+ OP_SUB,
+ OP_SHIFTL,
+ OP_SHIFTR,
+ OP_LESS,
+ OP_LESSEQ,
+ OP_EQ,
+ OP_NOTEQ,
+ OP_BAND,
+ OP_BOR,
+ OP_BXOR,
+ OP_LAND,
+ OP_LOR,
+ OP_CTERNARY,
+ OP_SUBSCRIPT
+};
+
+static const char*
+ins_name_str(const enum fspec_instruction name)
+{
+ switch (name) {
+ case INS_VERSION: return "version";
+ case INS_REG: return "reg";
+ case INS_PUSH: return "push";
+ case INS_PUSHR: return "pushr";
+ case INS_STORE: return "store";
+ case INS_OP: return "op";
+ case INS_QUEUE: return "queue";
+ case INS_IO: return "io";
+ case INS_EXEC: return "exec";
+ case INS_CALL: return "call";
+ case INS_JMP: return "jmp";
+ case INS_JMPIF: return "jmpif";
+ }
+ return "invalid";
+}
+
+static const char*
+op_name_str(const enum fspec_operation op)
+{
+ switch (op) {
+ case OP_UNM: return "unm";
+ case OP_LNOT: return "lnot";
+ case OP_BNOT: return "bnot";
+ case OP_MUL: return "mul";
+ case OP_DIV: return "div";
+ case OP_MOD: return "mod";
+ case OP_ADD: return "add";
+ case OP_SUB: return "sub";
+ case OP_SHIFTL: return "shiftl";
+ case OP_SHIFTR: return "shiftr";
+ case OP_LESS: return "less";
+ case OP_LESSEQ: return "lesseq";
+ case OP_EQ: return "eq";
+ case OP_NOTEQ: return "noteq";
+ case OP_BAND: return "band";
+ case OP_BOR: return "bor";
+ case OP_BXOR: return "bxor";
+ case OP_LAND: return "land";
+ case OP_LOR: return "lor";
+ case OP_CTERNARY: return "cternary";
+ case OP_SUBSCRIPT: return "subscript";
+ }
+ return "invalid";
+}
+
+static int
+disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len)
+{
+ union {
+ struct { unsigned name:5; unsigned n:2; uint64_t v:57; } ins;
+ uint8_t v[16];
+ } u = {0};
+
+ memcpy(u.v, buf, R_MIN(sizeof(u.v[0]), len));
+ const uint8_t insw = sizeof(uint16_t) * (1 << u.ins.n);
+ memcpy(u.v, buf, R_MIN(insw, len));
+ const char *buf_asm = "invalid";
+
+ if (u.ins.name == INS_OP)
+ buf_asm = sdb_fmt("%s %s", ins_name_str(u.ins.name), op_name_str(u.ins.v));
+ else if (u.ins.n == 0)
+ buf_asm = sdb_fmt("%s 0x%02x", ins_name_str(u.ins.name), (uint16_t)u.ins.v);
+ else if (u.ins.n == 1)
+ buf_asm = sdb_fmt("%s 0x%04x", ins_name_str(u.ins.name), (uint32_t)u.ins.v);
+ else if (u.ins.n == 2)
+ buf_asm = sdb_fmt("%s 0x%08x", ins_name_str(u.ins.name), (uint64_t)u.ins.v);
+ else
+ return 0;
+
+ r_strbuf_set(&op->buf_asm, buf_asm);
+ return (op->size = insw + (u.ins.name == INS_REG ? u.ins.v : 0));
+}
+
+RAsmPlugin r_asm_plugin_fspec = {
+ .name = "fspec",
+ .license = "LGPL3",
+ .desc = "fspec disassembly plugin",
+ .arch = "fspec",
+ .bits = 16 | 32 | 64,
+ .endian = R_SYS_ENDIAN_LITTLE,
+ .disassemble = disassemble
+};
+
+#ifndef CORELIB
+R_API RLibStruct radare_plugin = {
+ .type = R_LIB_TYPE_ASM,
+ .data = &r_asm_plugin_fspec,
+ .version = R2_VERSION
+};
+#endif