mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-08 19:33:31 +00:00
parent
45c41d4582
commit
af55ab712d
@ -10,7 +10,7 @@ all: ${ALL_TARGETS} ;
|
||||
|
||||
ALL_TARGETS=
|
||||
# TODO: rename to enabled plugins
|
||||
ARCHS=x86_udis.mk ppc.mk arm.mk avr.mk csr.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk
|
||||
ARCHS=x86_udis.mk ppc.mk arm.mk avr.mk csr.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk v850.mk
|
||||
include $(ARCHS)
|
||||
|
||||
clean:
|
||||
|
133
libr/anal/p/anal_v850.c
Normal file
133
libr/anal/p/anal_v850.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* radare - LGPL - Copyright 2012-2013 - pancake
|
||||
2014 - Fedor Sakharov <fedor.sakharov@gmail.com> */
|
||||
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
|
||||
#include <v850_disas.h>
|
||||
|
||||
static int v850_op(RAnal *anal, RAnalOp *op, ut64 addr,
|
||||
const ut8 *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
ut16 destaddr;
|
||||
st16 destaddrs;
|
||||
ut16 word1;
|
||||
struct v850_cmd cmd;
|
||||
|
||||
memset (&cmd, 0, sizeof (cmd));
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
|
||||
ret = op->size = v850_decode_command (buf, &cmd);
|
||||
|
||||
if (ret <= 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
op->addr = addr;
|
||||
op->jump = op->fail = -1;
|
||||
op->ptr = op->val = -1;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, buf, 2, LIL_ENDIAN);
|
||||
|
||||
switch ((word1 >> 5) & 0x3F) {
|
||||
case V850_MOV_IMM5:
|
||||
case V850_MOV:
|
||||
case V850_SLDB:
|
||||
case V850_SSTB:
|
||||
case V850_SLDH:
|
||||
case V850_SSTH:
|
||||
case V850_SLDW:
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
break;
|
||||
case V850_NOT:
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
break;
|
||||
case V850_DIVH:
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
case V850_JMP:
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
break;
|
||||
case V850_OR:
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case V850_MULH:
|
||||
case V850_MULH_IMM5:
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
break;
|
||||
case V850_XOR:
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case V850_AND:
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case V850_CMP:
|
||||
case V850_TST:
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case V850_SUBR:
|
||||
case V850_SUB:
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case V850_ADD:
|
||||
case V850_ADD_IMM5:
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case V850_SHR_IMM5:
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case V850_SAR_IMM5:
|
||||
op->type = R_ANAL_OP_TYPE_SAR;
|
||||
break;
|
||||
case V850_SHL_IMM5:
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case V850_BCOND:
|
||||
case V850_BCOND2:
|
||||
case V850_BCOND3:
|
||||
case V850_BCOND4:
|
||||
destaddr = ((((word1 >> 4) & 0x7) |
|
||||
((word1 >> 11) << 3)) << 1);
|
||||
if (destaddr & 0x100) {
|
||||
destaddrs = destaddr | 0xFE00;
|
||||
} else {
|
||||
destaddrs = destaddr;
|
||||
}
|
||||
|
||||
op->jump = addr + destaddrs;
|
||||
op->fail = addr + 2;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_v850 = {
|
||||
.name = "v850",
|
||||
.desc = "V850 code analysis plugin",
|
||||
.license = "LGPL3",
|
||||
.arch = R_SYS_ARCH_V850,
|
||||
.bits = 32,
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.op = v850_op,
|
||||
.set_reg_profile = NULL,
|
||||
.fingerprint_bb = NULL,
|
||||
.fingerprint_fcn = NULL,
|
||||
.diff_bb = NULL,
|
||||
.diff_fcn = NULL,
|
||||
.diff_eval = NULL,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_v850,
|
||||
};
|
||||
#endif
|
12
libr/anal/p/v850.mk
Normal file
12
libr/anal/p/v850.mk
Normal file
@ -0,0 +1,12 @@
|
||||
OBJ_V850=anal_v850.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_V850}
|
||||
OBJ_V850+=../../../../../../../../../../../../../../../../../../../../${LTOP}/asm/arch/v850/v850_disas.o
|
||||
TARGET_V850=anal_v850.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_V850}
|
||||
|
||||
${TARGET_V850}: ${OBJ_V850} ${SHARED_OBJ}
|
||||
$(call pwd)
|
||||
${CC} $(call libname,anal_v850) ${CFLAGS} \
|
||||
-I../../include/ -o ${TARGET_V850} ${OBJ_V850}
|
379
libr/asm/arch/v850/v850_disas.c
Normal file
379
libr/asm/arch/v850/v850_disas.c
Normal file
@ -0,0 +1,379 @@
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
|
||||
#include "v850_disas.h"
|
||||
|
||||
static const char *instrs[] = {
|
||||
[V850_MOV] = "mov",
|
||||
[V850_NOT] = "not",
|
||||
[V850_DIVH] = "divh",
|
||||
[V850_JMP] = "jmp",
|
||||
[V850_SATSUBR] = "satsubr",
|
||||
[V850_SATSUB] = "stasub",
|
||||
[V850_SATADD] = "satadd",
|
||||
[V850_MULH] = "mulh",
|
||||
[V850_OR] = "or",
|
||||
[V850_XOR] = "xor",
|
||||
[V850_AND] = "and",
|
||||
[V850_TST] = "tst",
|
||||
[V850_SUBR] = "subr",
|
||||
[V850_SUB] = "sub",
|
||||
[V850_ADD] = "add",
|
||||
[V850_CMP] = "cmp",
|
||||
[V850_MOV_IMM5] = "mov",
|
||||
[V850_SATADD_IMM5] = "satadd",
|
||||
[V850_ADD_IMM5] = "add",
|
||||
[V850_CMP_IMM5] = "cmp",
|
||||
[V850_SHR_IMM5] = "shr",
|
||||
[V850_SAR_IMM5] = "sar",
|
||||
[V850_SHL_IMM5] = "shl",
|
||||
[V850_MULH_IMM5] = "mulh",
|
||||
[V850_SLDB] = "sldb",
|
||||
[V850_SSTB] = "sstb",
|
||||
[V850_SLDH] = "sldh",
|
||||
[V850_SSTH] = "ssth",
|
||||
[V850_SLDW] = "sldw",
|
||||
[V850_SSTW] = "sstw",
|
||||
[V850_BCOND] = "bcond",
|
||||
[V850_ADDI] = "addi",
|
||||
[V850_MOVEA] = "movea",
|
||||
[V850_MOVHI] = "movhi",
|
||||
[V850_SATSUBI] = "satsubi",
|
||||
[V850_ORI] = "ori",
|
||||
[V850_XORI] = "xori",
|
||||
[V850_ANDI] = "andi",
|
||||
[V850_MULHI] = "mulhi",
|
||||
[V850_LDB] = "ld",
|
||||
[V850_LDHW] = "ld",
|
||||
[V850_STB] = "st",
|
||||
[V850_STHW] = "st",
|
||||
[V850_JARL1] = "jarl",
|
||||
[V850_JARL2] = "jarl",
|
||||
[V850_BIT_MANIP] = "",
|
||||
[V850_EXT1] = "",
|
||||
};
|
||||
|
||||
static const char *bit_instrs[] = {
|
||||
[V850_BIT_SET1] = "set1",
|
||||
[V850_BIT_NOT1] = "not1",
|
||||
[V850_BIT_CLR1] = "clr1",
|
||||
[V850_BIT_TST1] = "tst1",
|
||||
};
|
||||
|
||||
static const char *ext_instrs1[] = {
|
||||
[V850_EXT_SETF] = "setf",
|
||||
[V850_EXT_LDSR] = "ldsr",
|
||||
[V850_EXT_STSR] = "stsr",
|
||||
[V850_EXT_SHR] = "shr",
|
||||
[V850_EXT_SAR] = "sar",
|
||||
[V850_EXT_SHL] = "shl",
|
||||
[V850_EXT_TRAP] = "trap",
|
||||
[V850_EXT_HALT] = "halt",
|
||||
[V850_EXT_RETI] = "reti",
|
||||
[V850_EXT_EXT2] = "ext2",
|
||||
};
|
||||
|
||||
static const char *ext_instrs2[] = {
|
||||
[V850_EXT_DI] = "di",
|
||||
[V850_EXT_EI] = "ei",
|
||||
};
|
||||
|
||||
static const char *conds[] = {
|
||||
[V850_COND_V] = "v",
|
||||
[V850_COND_CL] = "cl",
|
||||
[V850_COND_Z] = "z",
|
||||
[V850_COND_NH] = "nh",
|
||||
[V850_COND_SN] = "sn",
|
||||
[V850_COND_T] = "t",
|
||||
[V850_COND_LT] = "lt",
|
||||
[V850_COND_LE] = "le",
|
||||
[V850_COND_NV] = "nv",
|
||||
[V850_COND_NC] = "nc",
|
||||
[V850_COND_NZ] = "nz",
|
||||
[V850_COND_H] = "h",
|
||||
[V850_COND_NS] = "ns",
|
||||
[V850_COND_SA] = "sa",
|
||||
[V850_COND_GE] = "ge",
|
||||
[V850_COND_GT] = "gt",
|
||||
};
|
||||
|
||||
static inline ut8 get_opcode(const ut16 instr) {
|
||||
return (instr >> 5) & 0x3F;
|
||||
}
|
||||
|
||||
static inline ut8 get_reg1(const ut16 instr) {
|
||||
return instr & 0x1F;
|
||||
}
|
||||
|
||||
static inline ut8 get_reg2(const ut16 instr) {
|
||||
return instr >> 11;
|
||||
}
|
||||
|
||||
static int decode_reg_reg(const ut16 instr, struct v850_cmd *cmd) {
|
||||
ut8 opcode;
|
||||
|
||||
opcode = get_opcode (instr);
|
||||
|
||||
if (opcode > sizeof (instrs)/sizeof (char *)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s", instrs[opcode]);
|
||||
|
||||
if (opcode == V850_JMP) {
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "[r%u]",
|
||||
get_reg1 (instr));
|
||||
} else {
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%u, r%u",
|
||||
get_reg1 (instr), get_reg2 (instr));
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int decode_imm_reg(const ut16 instr, struct v850_cmd *cmd) {
|
||||
ut8 opcode;
|
||||
st8 immed;
|
||||
|
||||
opcode = get_opcode (instr);
|
||||
|
||||
if (opcode > sizeof (instrs)/sizeof (char *)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s", instrs[opcode]);
|
||||
|
||||
immed = get_reg1 (instr);
|
||||
|
||||
if (immed & 0x10) {
|
||||
immed |= 0xE0;
|
||||
}
|
||||
|
||||
if (immed >= -9 && immed <= 9) {
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "%d, r%u",
|
||||
immed, get_reg2 (instr));
|
||||
} else {
|
||||
if (immed >= 0) {
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1,
|
||||
"0x%x, r%u", immed, get_reg2 (instr));
|
||||
} else {
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1,
|
||||
"-0x%x, r%u", immed * -1, get_reg2 (instr));
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int decode_bcond(const ut16 instr, struct v850_cmd *cmd) {
|
||||
ut16 disp;
|
||||
|
||||
disp = ((instr >> 4) & 0x7) | (instr >> 11);
|
||||
disp = disp << 1;
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "b%s", conds[instr & 0xF]);
|
||||
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%x", disp);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int decode_jarl(const ut8 *instr, struct v850_cmd *cmd) {
|
||||
ut8 reg;
|
||||
ut16 word1, word2;
|
||||
ut32 disp;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, instr, 2, LIL_ENDIAN);
|
||||
r_mem_copyendian ((ut8*)&word2, instr + 2, 2, LIL_ENDIAN);
|
||||
|
||||
reg = get_reg2 (word1);
|
||||
disp = (word2 << 6) | get_reg1 (word1);
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s", instrs[get_opcode (word1)]);
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%08x, r%d",
|
||||
disp << 1, reg);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int decode_3operands(const ut8 *instr, struct v850_cmd *cmd) {
|
||||
ut16 word1, word2;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, instr, 2, LIL_ENDIAN);
|
||||
r_mem_copyendian ((ut8*)&word2, instr + 2, 2, LIL_ENDIAN);
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s", instrs[get_opcode (word1)]);
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%x, r%d, r%d",
|
||||
word2, get_reg1 (word1), get_reg2 (word1));
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int decode_load_store(const ut8 *instr, struct v850_cmd *cmd) {
|
||||
ut16 word1, word2;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, instr, 2, LIL_ENDIAN);
|
||||
r_mem_copyendian ((ut8*)&word2, instr + 2, 2, LIL_ENDIAN);
|
||||
|
||||
switch (get_opcode (word1)) {
|
||||
case V850_STB:
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s.b", instrs[get_opcode (word1)]);
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%d, 0x%x[r%d]",
|
||||
get_reg2 (word1), word2, get_reg1 (word1));
|
||||
break;
|
||||
case V850_LDB:
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s.b", instrs[get_opcode (word1)]);
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%x[r%d], r%d",
|
||||
get_reg1 (word1), word2, get_reg2 (word1));
|
||||
break;
|
||||
case V850_LDHW:
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s.%c",
|
||||
instrs[get_opcode (word1)], word2 & 1 ? 'w' : 'h');
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%x[r%d], r%d",
|
||||
word2 & 0xFFFE, get_reg1 (word1), get_reg2 (word1));
|
||||
break;
|
||||
case V850_STHW:
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s.%c",
|
||||
instrs[get_opcode (word1)], word2 & 1 ? 'w' : 'h');
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%d, 0x%x[r%d]",
|
||||
get_reg2 (word1), word2 & 0xFFFE, get_reg1 (word1));
|
||||
break;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int decode_bit_op(const ut8 *instr, struct v850_cmd *cmd) {
|
||||
ut16 word1, word2;
|
||||
ut8 reg1;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, instr, 2, LIL_ENDIAN);
|
||||
r_mem_copyendian ((ut8*)&word2, instr + 2, 2, LIL_ENDIAN);
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s", bit_instrs[word1 >> 14]);
|
||||
|
||||
reg1 = get_reg1 (word1);
|
||||
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "%u, 0x%x[r%d]",
|
||||
(word1 >> 11) & 0x7, word2, reg1);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int decode_extended(const ut8 *instr, struct v850_cmd *cmd) {
|
||||
ut16 word1, word2;
|
||||
|
||||
r_mem_copyendian ((ut8*)&word1, instr, 2, LIL_ENDIAN);
|
||||
r_mem_copyendian ((ut8*)&word2, instr + 2, 2, LIL_ENDIAN);
|
||||
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s",
|
||||
ext_instrs1[get_opcode (word1)]);
|
||||
|
||||
switch (get_opcode (word1)) {
|
||||
case V850_EXT_SETF:
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "%s, r%d",
|
||||
conds[word1 & 0xF], get_reg2 (word1));
|
||||
break;
|
||||
case V850_EXT_LDSR:
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%d, r%d",
|
||||
get_reg2 (word1), get_reg1(word1));
|
||||
break;
|
||||
case V850_EXT_STSR:
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%d, r%d",
|
||||
get_reg1 (word1), get_reg2 (word1));
|
||||
break;
|
||||
case V850_EXT_SHR:
|
||||
case V850_EXT_SAR:
|
||||
case V850_EXT_SHL:
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "r%d, r%d",
|
||||
get_reg1 (word1), get_reg2 (word2));
|
||||
break;
|
||||
case V850_EXT_TRAP:
|
||||
snprintf (cmd->operands, V850_INSTR_MAXLEN - 1, "0x%x",
|
||||
get_reg1 (word1));
|
||||
break;
|
||||
case V850_EXT_HALT:
|
||||
case V850_EXT_RETI:
|
||||
cmd->operands[0] = '\0';
|
||||
break;
|
||||
case V850_EXT_EXT2:
|
||||
snprintf (cmd->instr, V850_INSTR_MAXLEN - 1, "%s",
|
||||
ext_instrs2[word2 >> 13]);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
int v850_decode_command (const ut8 *instr, struct v850_cmd *cmd) {
|
||||
int ret;
|
||||
ut16 in;
|
||||
|
||||
r_mem_copyendian ((ut8*)&in, instr, 2, LIL_ENDIAN);
|
||||
|
||||
switch (get_opcode (in)) {
|
||||
case V850_MOV:
|
||||
case V850_NOT:
|
||||
case V850_DIVH:
|
||||
case V850_JMP:
|
||||
case V850_SATSUBR:
|
||||
case V850_SATSUB:
|
||||
case V850_SATADD:
|
||||
case V850_MULH:
|
||||
case V850_OR:
|
||||
case V850_XOR:
|
||||
case V850_AND:
|
||||
case V850_TST:
|
||||
case V850_SUBR:
|
||||
case V850_SUB:
|
||||
case V850_ADD:
|
||||
case V850_CMP:
|
||||
ret = decode_reg_reg (in, cmd);
|
||||
break;
|
||||
case V850_MOV_IMM5:
|
||||
case V850_SATADD_IMM5:
|
||||
case V850_ADD_IMM5:
|
||||
case V850_CMP_IMM5:
|
||||
case V850_SHR_IMM5:
|
||||
case V850_SAR_IMM5:
|
||||
case V850_SHL_IMM5:
|
||||
case V850_MULH_IMM5:
|
||||
ret = decode_imm_reg (in, cmd);
|
||||
break;
|
||||
case V850_ADDI:
|
||||
case V850_MOVEA:
|
||||
case V850_MOVHI:
|
||||
case V850_SATSUBI:
|
||||
case V850_ORI:
|
||||
case V850_XORI:
|
||||
case V850_ANDI:
|
||||
case V850_MULHI:
|
||||
ret = decode_3operands (instr, cmd);
|
||||
break;
|
||||
case V850_JARL1:
|
||||
case V850_JARL2:
|
||||
ret = decode_jarl (instr, cmd);
|
||||
break;
|
||||
case V850_STB:
|
||||
case V850_LDB:
|
||||
case V850_LDHW:
|
||||
case V850_STHW:
|
||||
ret = decode_load_store (instr, cmd);
|
||||
break;
|
||||
case V850_BIT_MANIP:
|
||||
ret = decode_bit_op (instr, cmd);
|
||||
break;
|
||||
case V850_EXT1:
|
||||
ret = decode_extended (instr, cmd);
|
||||
break;
|
||||
default:
|
||||
if ((get_opcode (in) >> 2) == 0xB) {
|
||||
ret = decode_bcond (in, cmd);
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -13,7 +13,7 @@ ALL_TARGETS=
|
||||
# TODO: rename to enabled plugins
|
||||
ARCHS=mips.mk sparc.mk java.mk bf.mk arm.mk dalvik.mk x86_as.mk x86_nz.mk
|
||||
ARCHS+=ppc.mk x86_olly.mk x86.mk csr.mk x86_nasm.mk psosvm.mk avr.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk 6502.mk h8300.mk cr16.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk 6502.mk h8300.mk cr16.mk v850.mk
|
||||
include $(ARCHS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
39
libr/asm/p/asm_v850.c
Normal file
39
libr/asm/p/asm_v850.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include <v850_disas.h>
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
int ret = R_TRUE;
|
||||
struct v850_cmd cmd;
|
||||
|
||||
ret = v850_decode_command (buf, &cmd);
|
||||
|
||||
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s %s", cmd.instr, cmd.operands);
|
||||
op->size = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_v850 = {
|
||||
.name = "v850",
|
||||
.license = "LGPL3",
|
||||
.desc = "v850 disassembly plugin",
|
||||
.arch = "v850",
|
||||
.bits = 32,
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.modify = NULL,
|
||||
.assemble = NULL
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_v850
|
||||
};
|
||||
#endif
|
11
libr/asm/p/v850.mk
Normal file
11
libr/asm/p/v850.mk
Normal file
@ -0,0 +1,11 @@
|
||||
OBJ_V850=asm_v850.o
|
||||
OBJ_V850+=../arch/v850/v850_disas.o
|
||||
|
||||
|
||||
STATIC_OBJ+=${OBJ_V850}
|
||||
TARGET_V850=asm_v850.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_V850}
|
||||
|
||||
${TARGET_V850}: ${OBJ_V850}
|
||||
${CC} ${LDFLAGS} ${CFLAGS} -I../arch/v850 -o ${TARGET_V850} ${OBJ_V850}
|
@ -1200,6 +1200,7 @@ extern RAnalPlugin r_anal_plugin_malbolge;
|
||||
extern RAnalPlugin r_anal_plugin_ws;
|
||||
extern RAnalPlugin r_anal_plugin_h8300;
|
||||
extern RAnalPlugin r_anal_plugin_cr16;
|
||||
extern RAnalPlugin r_anal_plugin_v850;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -196,6 +196,7 @@ extern RAsmPlugin r_asm_plugin_ws;
|
||||
extern RAsmPlugin r_asm_plugin_6502;
|
||||
extern RAsmPlugin r_asm_plugin_h8300;
|
||||
extern RAsmPlugin r_asm_plugin_cr16;
|
||||
extern RAsmPlugin r_asm_plugin_v850;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -306,6 +306,7 @@ enum {
|
||||
R_SYS_ARCH_EBC = 0x100000,
|
||||
R_SYS_ARCH_H8300 = 0x8300,
|
||||
R_SYS_ARCH_CR16 = 0xc160,
|
||||
R_SYS_ARCH_V850 = 0x0850, //XXX fixme
|
||||
};
|
||||
|
||||
/* os */
|
||||
|
111
libr/include/v850_disas.h
Normal file
111
libr/include/v850_disas.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef R2_V850_DISASM_H
|
||||
#define R2_V850_DISASM_H
|
||||
|
||||
#define V850_INSTR_MAXLEN 24
|
||||
|
||||
enum v850_cmd_opcodes {
|
||||
V850_MOV = 0x0,
|
||||
V850_NOT = 0x1,
|
||||
V850_DIVH = 0x2,
|
||||
V850_JMP = 0x3,
|
||||
V850_SATSUBR = 0x4,
|
||||
V850_SATSUB = 0x5,
|
||||
V850_SATADD = 0x6,
|
||||
V850_MULH = 0x7,
|
||||
V850_OR = 0x8,
|
||||
V850_XOR = 0x9,
|
||||
V850_AND = 0xA,
|
||||
V850_TST = 0xB,
|
||||
V850_SUBR = 0xC,
|
||||
V850_SUB = 0xD,
|
||||
V850_ADD = 0xE,
|
||||
V850_CMP = 0xF,
|
||||
V850_MOV_IMM5 = 0x10,
|
||||
V850_SATADD_IMM5 = 0x11,
|
||||
V850_ADD_IMM5 = 0x12,
|
||||
V850_CMP_IMM5 = 0x13,
|
||||
V850_SHR_IMM5 = 0x14,
|
||||
V850_SAR_IMM5 = 0x15,
|
||||
V850_SHL_IMM5 = 0x16,
|
||||
V850_MULH_IMM5 = 0x17,
|
||||
V850_SLDB = 0x18,
|
||||
V850_SSTB = 0x1C,
|
||||
V850_SLDH = 0x20,
|
||||
V850_SSTH = 0x24,
|
||||
V850_SLDW = 0x28,
|
||||
V850_SSTW = 0x28,
|
||||
V850_BCOND = 0x2C,
|
||||
V850_BCOND2 = 0x2D,
|
||||
V850_BCOND3 = 0x2E,
|
||||
V850_BCOND4 = 0x2F,
|
||||
V850_ADDI = 0x30,
|
||||
V850_MOVEA = 0x31,
|
||||
V850_MOVHI = 0x32,
|
||||
V850_SATSUBI = 0x33,
|
||||
V850_ORI = 0x34,
|
||||
V850_XORI = 0x35,
|
||||
V850_ANDI = 0x36,
|
||||
V850_MULHI = 0x37,
|
||||
V850_LDB = 0x38,
|
||||
V850_LDHW = 0x39,
|
||||
V850_STB = 0x3A,
|
||||
V850_STHW = 0x3B,
|
||||
V850_JARL1 = 0x3C,
|
||||
V850_JARL2 = 0x3D,
|
||||
V850_BIT_MANIP = 0x3E,
|
||||
V850_EXT1 = 0x3F,
|
||||
};
|
||||
|
||||
enum v850_conds {
|
||||
V850_COND_V = 0x0,
|
||||
V850_COND_CL = 0x1,
|
||||
V850_COND_Z = 0x2,
|
||||
V850_COND_NH = 0x3,
|
||||
V850_COND_SN = 0x4,
|
||||
V850_COND_T = 0x5,
|
||||
V850_COND_LT = 0x6,
|
||||
V850_COND_LE = 0x7,
|
||||
V850_COND_NV = 0x8,
|
||||
V850_COND_NC = 0x9,
|
||||
V850_COND_NZ = 0xA,
|
||||
V850_COND_H = 0xB,
|
||||
V850_COND_NS = 0xC,
|
||||
V850_COND_SA = 0xD,
|
||||
V850_COND_GE = 0xE,
|
||||
V850_COND_GT = 0xF,
|
||||
};
|
||||
|
||||
enum v850_bit_ops {
|
||||
V850_BIT_SET1 = 0x0,
|
||||
V850_BIT_NOT1 = 0x1,
|
||||
V850_BIT_CLR1 = 0x2,
|
||||
V850_BIT_TST1 = 0x3,
|
||||
};
|
||||
|
||||
enum v850_extension1 {
|
||||
V850_EXT_SETF = 0x0,
|
||||
V850_EXT_LDSR = 0x1,
|
||||
V850_EXT_STSR = 0x2,
|
||||
V850_EXT_UNDEF1 = 0x3,
|
||||
V850_EXT_SHR = 0x4,
|
||||
V850_EXT_SAR = 0x5,
|
||||
V850_EXT_SHL = 0x6,
|
||||
V850_EXT_UNDEF2 = 0x7,
|
||||
V850_EXT_TRAP = 0x8,
|
||||
V850_EXT_HALT = 0x9,
|
||||
V850_EXT_RETI = 0xa,
|
||||
V850_EXT_EXT2 = 0xb,
|
||||
};
|
||||
|
||||
enum v850_extension2 {
|
||||
V850_EXT_DI = 0x0,
|
||||
V850_EXT_EI = 0x4,
|
||||
};
|
||||
|
||||
struct v850_cmd {
|
||||
unsigned type;
|
||||
char instr[V850_INSTR_MAXLEN];
|
||||
char operands[V850_INSTR_MAXLEN];
|
||||
};
|
||||
|
||||
#endif /* R2_V850_DISASM_H */
|
@ -40,6 +40,7 @@ asm.h8300
|
||||
asm.malbolge
|
||||
asm.ws
|
||||
asm.cr16
|
||||
asm.v850
|
||||
anal.sh
|
||||
anal.x86_cs
|
||||
anal.x86_udis
|
||||
@ -68,6 +69,7 @@ anal.malbolge
|
||||
anal.ws
|
||||
anal.h8300
|
||||
anal.cr16
|
||||
anal.v850
|
||||
bin.any
|
||||
bin.bios
|
||||
bin.bf
|
||||
|
Loading…
Reference in New Issue
Block a user