msp430: Initial commit

This commit is contained in:
Fedor Sakharov 2014-09-23 11:36:37 +04:00 committed by pancake
parent c3461856e2
commit 2b0009b858
12 changed files with 755 additions and 2 deletions

View File

@ -10,7 +10,7 @@ all: ${ALL_TARGETS} ;
ALL_TARGETS=
# TODO: rename to enabled plugins
ARCHS=x86_udis.mk ppc.mk arm_gnu.mk avr.mk csr.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk v850.mk
ARCHS=x86_udis.mk ppc.mk arm_gnu.mk avr.mk csr.mk dalvik.mk sh.mk ebc.mk gb.mk malbolge.mk ws.mk h8300.mk cr16.mk v850.mk msp430.mk
include $(ARCHS)
clean:

88
libr/anal/p/anal_msp430.c Normal file
View File

@ -0,0 +1,88 @@
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include <r_util.h>
#include <msp430_disas.h>
static int msp430_op(RAnal *anal, RAnalOp *op, ut64 addr,
const ut8 *buf, int len)
{
int ret;
struct msp430_cmd cmd;
memset (&cmd, 0, sizeof (cmd));
memset (op, 0, sizeof (RAnalOp));
ret = op->size = msp430_decode_command (buf, &cmd);
if (ret < 0) {
return ret;
}
op->addr = addr;
op->jump = op->fail = UT64_MAX;
op->ptr = op->val = -1;
switch (cmd.type) {
case MSP430_ONEOP:
switch (cmd.opcode) {
case MSP430_RRA:
case MSP430_RCR:
op->type = R_ANAL_OP_TYPE_ROR; break;
case MSP430_PUSH:
op->type = R_ANAL_OP_TYPE_PUSH; break;
case MSP430_CALL:
op->type = R_ANAL_OP_TYPE_CALL; break;
case MSP430_RETI:
op->type = R_ANAL_OP_TYPE_RET; break;
}
break;
case MSP430_TWOOP:
case MSP430_BIT:
case MSP430_BIC:
case MSP430_BIS:
case MSP430_MOV: op->type = R_ANAL_OP_TYPE_MOV; break;
case MSP430_DADD:
case MSP430_ADDC:
case MSP430_ADD: op->type = R_ANAL_OP_TYPE_ADD; break;
case MSP430_SUBC:
case MSP430_SUB: op->type = R_ANAL_OP_TYPE_SUB; break;
case MSP430_CMP: op->type = R_ANAL_OP_TYPE_CMP; break;
case MSP430_XOR: op->type = R_ANAL_OP_TYPE_XOR; break;
case MSP430_AND: op->type = R_ANAL_OP_TYPE_AND; break;
break;
case MSP430_JUMP:
if (cmd.jmp_cond == MSP430_JMP) {
op->type = R_ANAL_OP_TYPE_JMP;
} else {
op->type = R_ANAL_OP_TYPE_CJMP;
}
op->jump = addr + cmd.jmp_addr;
op->fail = addr + 2;
break;
default:
op->type = R_ANAL_OP_TYPE_UNK;
}
return ret;
}
struct r_anal_plugin_t r_anal_plugin_msp430 = {
.name = "msp430",
.desc = "TI MSP430 code analysis plugin",
.license = "LGPL3",
.arch = R_SYS_ARCH_MSP430,
.bits = 16,
.init = NULL,
.fini = NULL,
.op = msp430_op,
.set_reg_profile = NULL,
.fingerprint_bb = NULL,
.fingerprint_fcn = NULL,
.diff_bb = NULL,
.diff_fcn = NULL,
.diff_eval = NULL,
};

12
libr/anal/p/msp430.mk Normal file
View File

@ -0,0 +1,12 @@
OBJ_msp430=anal_msp430.o
STATIC_OBJ+=${OBJ_msp430}
OBJ_msp430+=../../asm/arch/msp430/msp430_disas.o
TARGET_msp430=anal_msp430.${EXT_SO}
ALL_TARGETS+=${TARGET_msp430}
${TARGET_msp430}: ${OBJ_msp430} ${SHARED_OBJ}
$(call pwd)
${CC} $(call libname,anal_msp430) ${CFLAGS} \
-I../../include/ -o ${TARGET_msp430} ${OBJ_msp430}

View File

@ -0,0 +1,508 @@
#include <r_types.h>
#include <r_util.h>
#include "msp430_disas.h"
static const char *two_op_instrs[] = {
[MSP430_MOV] = "mov",
[MSP430_ADD] = "add",
[MSP430_ADDC] = "addc",
[MSP430_SUBC] = "subc",
[MSP430_SUB] = "sub",
[MSP430_CMP] = "cmp",
[MSP430_DADD] = "dadd",
[MSP430_BIT] = "bit",
[MSP430_BIC] = "bic",
[MSP430_BIS] = "bis",
[MSP430_XOR] = "xor",
[MSP430_AND] = "and",
};
static const char *one_op_instrs[] = {
[MSP430_RCR] = "rcr",
[MSP430_SWPB] = "swpb",
[MSP430_RRA] = "rra",
[MSP430_SXT] = "sxt",
[MSP430_PUSH] = "push",
[MSP430_CALL] = "call",
[MSP430_RETI] = "reti",
};
static const char *jmp_instrs[] = {
[MSP430_JEQ] = "jeq",
[MSP430_JNE] = "jnz",
[MSP430_JC] = "jc",
[MSP430_JNC] = "jnc",
[MSP430_JN] = "jn",
[MSP430_JGE] = "jge",
[MSP430_JL] = "jl",
[MSP430_JMP] = "jmp",
};
static ut8 get_twoop_opcode(ut16 instr)
{
return instr >> 12;
}
static ut8 get_as(ut16 instr)
{
return (instr >> 4) & 3;
}
static ut8 get_bw(ut16 instr)
{
return (instr >> 6) & 1;
}
static ut8 get_ad(ut16 instr)
{
return (instr >> 7) & 1;
}
static int get_src (instr) {
return (instr >> 8) & 0xF;
}
static int get_dst (instr) {
return instr & 0xF;
}
static void remove_first_operand (struct msp430_cmd *cmd)
{
if (strchr (cmd->operands, ',')) {
memmove (cmd->operands, strchr (cmd->operands, ',') + 2,
strlen (strchr (cmd->operands, ',') + 2) + 1);
}
}
static void remove_second_operand (struct msp430_cmd *cmd)
{
if (strchr (cmd->operands, ','))
*strchr (cmd->operands, ',') = '\0';
}
/* TODO: This is ugly as hell */
static int decode_emulation (ut16 instr, ut16 dst, struct msp430_cmd *cmd)
{
int ret = -1;
ut8 as, opcode;
as = get_as (instr);
opcode = get_twoop_opcode (instr);
if (as == 0 && get_src (instr) == MSP430_R3 && opcode == MSP430_ADDC) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "adc.b" : "adc");
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#0, r%d",
get_dst (instr));
} else if (opcode == MSP430_MOV && as == 0 && get_src (instr) == MSP430_R3
&& get_dst (instr) != MSP430_R3 && get_ad (instr) == 0) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "clr.b" : "clr");
remove_first_operand (cmd);
} else if (opcode == MSP430_MOV && as != 3 && get_dst (instr) == MSP430_PC
&& get_src (instr) != MSP430_SP) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", "br");
remove_second_operand (cmd);
} else if (opcode == MSP430_BIC && as == 2 && get_src (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", "clrn");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_BIC && as == 2 && get_src (instr) == 3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", "clrz");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_DADD && as == 0 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "dadc.b" : "dadc");
remove_second_operand (cmd);
} else if (opcode == MSP430_SUB && as == 1 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "dec.b" : "dec");
remove_second_operand (cmd);
} else if (opcode == MSP430_SUB && as == 2 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "decd.b" : "decd");
remove_first_operand (cmd);
} else if (opcode == MSP430_BIC && as == 3 && get_src (instr) == MSP430_SR
&& get_dst (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", "dint");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_BIS && as == 3 && get_src (instr) == MSP430_SR
&& get_dst (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", "eint");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_ADD && as == 1 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "inc.b" : "inc");
remove_second_operand (cmd);
} else if (opcode == MSP430_ADD && as == 2 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "incd.b" : "incd");
remove_second_operand (cmd);
} else if (opcode == MSP430_XOR && as == 3 && get_src (instr) != MSP430_R3
&& get_src (instr) != MSP430_SR && (dst == 0xFFFF || dst == 0xFF)) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "inv.b" : "inv");
remove_second_operand (cmd);
} else if (opcode == MSP430_MOV && as == 0 && get_src (instr) == MSP430_R3
&& get_ad (instr) == 0 && get_dst (instr) == 3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "nop");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_MOV && as == 3 && get_src (instr) == MSP430_SP
&& get_dst (instr) != MSP430_PC) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "pop.b" : "pop");
remove_second_operand (cmd);
} else if (opcode == MSP430_MOV && as == 3 && get_src (instr) == MSP430_SP
&& get_dst (instr) == MSP430_PC) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "ret");
cmd->type = MSP430_ONEOP;
cmd->opcode = MSP430_RETI;
cmd->operands[0] = '\0';
} else if (opcode == MSP430_ADD && get_src (instr) == get_dst (instr)) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "rla.b" : "rla");
remove_second_operand (cmd);
} else if (opcode == MSP430_ADDC && get_src (instr) == get_dst (instr)) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "rlc.b" : "rlc");
remove_second_operand (cmd);
} else if (opcode == MSP430_SUBC && as == 0 && get_src (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "sbc.b" : "sbc");
remove_second_operand (cmd);
} else if (opcode == MSP430_BIS && as == 1 && get_dst (instr) == MSP430_R3) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "setc");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_BIS && as == 2 && get_dst (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "setn");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_BIS && as == 2 && get_dst (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "setz");
cmd->operands[0] = '\0';
} else if (opcode == MSP430_CMP && as == 0 && get_src (instr) == MSP430_SR) {
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
get_bw (instr) ? "tst.b" : "tst");
remove_first_operand (cmd);
}
return ret;
}
static int decode_addressing_mode (ut16 instr, ut16 dst, ut16 op2, struct msp430_cmd *cmd)
{
int ret;
ut8 as, ad;
char dstbuf[16];
memset (dstbuf, 0, sizeof (dstbuf));
as = get_as (instr);
ad = get_ad (instr);
switch (as) {
case 0:
switch (get_src (instr)) {
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#0");
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"r%d", get_src (instr));
}
ret = 2;
break;
case 1:
ret = 4;
switch (get_src (instr)) {
case MSP430_PC:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"0x%04x", dst);
break;
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "%s", "#1");
ret = 2;
break;
case MSP430_SR:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"&0x%04x", dst);
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"0x%x(r%d)", dst, get_src (instr));
}
break;
case 2:
switch (get_src (instr)) {
case MSP430_SR:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#4");
break;
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#2");
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"@r%d", get_src (instr));
}
ret = 2;
break;
case 3:
ret = 2;
switch (get_src (instr)) {
case MSP430_SR:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#8");
break;
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#-1");
break;
case MSP430_PC:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"#0x%04x", dst);
ret = 4;
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"@r%d+", get_src (instr));
}
break;
default:
ret = -1;
}
if (ret < 0)
return ret;
switch (ad) {
case 0:
snprintf (dstbuf, 15, ", r%d", get_dst (instr));
break;
case 1:
switch (get_dst(instr)) {
case MSP430_PC:
snprintf (dstbuf, 15, ", 0x%04x", dst);
if (ret == 2)
ret = 4;
break;
case MSP430_SR:
if (as == 1 && get_src (instr) == 2) {
snprintf (dstbuf, 15, ", &0x%04x", op2);
ret = 6;
} else {
snprintf (dstbuf, 15, ", &0x%04x", dst);
ret = 4;
}
break;
default:
if (as == 1 && get_src (instr) != 0 && get_src (instr) != 2
&& get_src (instr) != 3) {
snprintf (dstbuf, 15, ", 0x%x(r%d)", op2, get_dst (instr));
ret = 6;
} else {
snprintf (dstbuf, 15, ", 0x%x(r%d)", dst, get_dst (instr));
if (ret == 2)
ret = 4;
}
}
break;
default:
ret = -1;
}
strncat (cmd->operands, dstbuf, MSP430_INSTR_MAXLEN - 1
- strlen (cmd->operands));
decode_emulation (instr, dst, cmd);
return ret;
}
static int decode_twoop_opcode(ut16 instr, ut16 src, ut16 op2, struct msp430_cmd *cmd)
{
int ret;
ut8 opcode;
opcode = get_twoop_opcode (instr);
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s", two_op_instrs[opcode]);
if (get_bw(instr)) {
strncat (cmd->instr, ".b", MSP430_INSTR_MAXLEN - 1 - strlen (cmd->instr));
}
cmd->opcode = get_twoop_opcode (instr);
ret = decode_addressing_mode (instr, src, op2, cmd);
return ret;
}
static ut8 get_jmp_opcode(ut16 instr)
{
return instr >> 13;
}
static ut8 get_jmp_cond(ut16 instr)
{
return (instr >> 10 ) & 7;
}
static int decode_jmp (ut16 instr, struct msp430_cmd *cmd)
{
ut16 addr;
if (get_jmp_opcode(instr) != MSP430_JMP_OPC)
return -1;
snprintf(cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
jmp_instrs[get_jmp_cond (instr)]);
addr = instr & 0x3FF;
cmd->jmp_addr = addr >= 0x300 ? (st16)((0xFE00 | addr) * 2 + 2) : (addr & 0x1FF) * 2 + 2;
snprintf(cmd->operands, MSP430_INSTR_MAXLEN - 1,
"$%c0x%04x", addr >= 0x300 ? '-' : '+',
addr >= 0x300 ? 0x400 - ((addr & 0x1FF) * 2 + 2) : (addr & 0x1FF) * 2 + 2);
cmd->jmp_cond = get_jmp_cond (instr);
cmd->opcode = get_jmp_opcode (instr);
cmd->type = MSP430_JUMP;
return 2;
}
static int get_oneop_opcode(ut16 instr)
{
return (instr >> 7) & 0x7;
}
static int decode_oneop_opcode(ut16 instr, ut16 op, struct msp430_cmd *cmd)
{
int ret = 2;
ut8 ad, opcode;
if ((instr >> 10) != 4)
return -1;
opcode = get_oneop_opcode (instr);
ad = get_as (instr);
snprintf (cmd->instr, MSP430_INSTR_MAXLEN - 1, "%s",
one_op_instrs[opcode]);
cmd->opcode = get_oneop_opcode (instr);
switch (get_oneop_opcode(instr)) {
case MSP430_RCR:
case MSP430_SWPB:
case MSP430_RRA:
case MSP430_SXT:
case MSP430_PUSH:
case MSP430_CALL:
switch (ad) {
case 0:
switch (get_dst (instr)) {
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#0");
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"r%d", get_dst (instr));
}
ret = 2;
break;
case 1:
switch (get_dst (instr)) {
case MSP430_PC:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"0x%04x", op);
break;
case MSP430_SR:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"&0x%04x", op);
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"0x%x(r%d)", op, get_dst (instr));
}
ret = 4;
break;
case 2:
switch (get_dst (instr)) {
case MSP430_SR:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#4");
break;
case MSP430_R3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1, "#2");
break;
default:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"@r%d", get_dst(instr));
}
ret = 2;
break;
case 3:
snprintf (cmd->operands, MSP430_INSTR_MAXLEN - 1,
"#0x%04x", op);
ret = 4;
break;
default:
ret = -1;
}
break;
case MSP430_RETI:
cmd->operands[0] = '\0';
break;
}
cmd->type = MSP430_ONEOP;
return ret;
}
int msp430_decode_command(const ut8 *in, struct msp430_cmd *cmd)
{
int ret = -1;
ut16 instr;
ut16 operand1, operand2;
ut8 opcode;
r_mem_copyendian((ut8*)&instr, in, sizeof (ut16), LIL_ENDIAN);
opcode = get_twoop_opcode (instr);
switch (opcode) {
case MSP430_MOV:
case MSP430_ADD:
case MSP430_ADDC:
case MSP430_SUBC:
case MSP430_SUB:
case MSP430_CMP:
case MSP430_DADD:
case MSP430_BIT:
case MSP430_BIC:
case MSP430_BIS:
case MSP430_XOR:
case MSP430_AND:
cmd->type = MSP430_TWOOP;
r_mem_copyendian((ut8*)&operand1, in + 2, sizeof (ut16), LIL_ENDIAN);
r_mem_copyendian((ut8*)&operand2, in + 4, sizeof (ut16), LIL_ENDIAN);
ret = decode_twoop_opcode(instr, operand1, operand2, cmd);
break;
}
if (ret > 0) {
return ret;
}
ret = decode_jmp (instr, cmd);
if (ret > 0)
return ret;
r_mem_copyendian((ut8*)&operand1, in + 2, sizeof (ut16), LIL_ENDIAN);
ret = decode_oneop_opcode (instr, operand1, cmd);
return ret;
}

View File

@ -13,7 +13,7 @@ ALL_TARGETS=
# TODO: rename to enabled plugins
ARCHS=mips_gnu.mk sparc.mk java.mk bf.mk arm_gnu.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 v850.mk spc700.mk propeller.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 spc700.mk propeller.mk msp430.mk
include $(ARCHS)
all: ${ALL_TARGETS}

43
libr/asm/p/asm_msp430.c Normal file
View File

@ -0,0 +1,43 @@
#include <stdio.h>
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <msp430_disas.h>
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len)
{
int ret;
struct msp430_cmd cmd;
ret = msp430_decode_command (buf, &cmd);
if (ret > 0) {
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s %s", cmd.instr, cmd.operands);
}
op->size = ret;
return ret;
}
RAsmPlugin r_asm_plugin_msp430 = {
.name = "msp430",
.license = "LGPL3",
.desc = "msp430 disassembly plugin",
.arch = "msp430",
.bits = 16,
.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_propeller,
};
#endif

10
libr/asm/p/msp430.mk Normal file
View File

@ -0,0 +1,10 @@
OBJ_MSP430=asm_msp430.o
OBJ_MSP430+=../arch/msp430/msp430_disas.o
STATIC_OBJ+=${OBJ_MSP430}
TARGET_MSP430=asm_msp430.${EXT_SO}
ALL_TARGETS+=${TARGET_MSP430}
${TARGET_MSP430}: ${OBJ_MSP430}
${CC} ${LDFLAGS} ${CFLAGS} -I../arch/msp430 -o ${TARGET_MSP430} ${OBJ_MSP430}

View File

@ -0,0 +1,87 @@
#ifndef MSP430_DISAS_H
#define MSP430_DISAS_H
#define MSP430_INSTR_MAXLEN 32
enum msp430_oneop_opcodes {
MSP430_RCR,
MSP430_SWPB,
MSP430_RRA,
MSP430_SXT,
MSP430_PUSH,
MSP430_CALL,
MSP430_RETI,
MSP430_UNUSED,
};
enum msp430_jumps {
MSP430_JNE,
MSP430_JEQ,
MSP430_JNC,
MSP430_JC,
MSP430_JN,
MSP430_JGE,
MSP430_JL,
MSP430_JMP,
};
enum msp430_twoop_opcodes {
MSP430_JMP_OPC = 0x1,
MSP430_MOV = 0x4,
MSP430_ADD,
MSP430_ADDC,
MSP430_SUBC,
MSP430_SUB,
MSP430_CMP,
MSP430_DADD,
MSP430_BIT,
MSP430_BIC,
MSP430_BIS,
MSP430_XOR,
MSP430_AND,
};
enum msp430_addr_modes {
MSP430_DIRECT,
MSP430_INDEXED,
MSP430_INDIRECT,
MSP430_INDIRECT_INC,
};
enum msp430_cmd_type {
MSP430_ONEOP,
MSP430_TWOOP,
MSP430_JUMP,
};
enum msp430_registers {
MSP430_PC,
MSP430_SP,
MSP430_SR,
MSP430_R3,
MSP430_R4,
MSP430_R5,
MSP430_R6,
MSP430_R7,
MSP430_R8,
MSP430_R9,
MSP430_R10,
MSP430_R11,
MSP430_R12,
MSP430_R13,
MSP430_R14,
MSP430_R15,
};
struct msp430_cmd {
ut8 type;
ut16 opcode;
st16 jmp_addr;
ut16 call_addr;
ut8 jmp_cond;
char instr[MSP430_INSTR_MAXLEN];
char operands[MSP430_INSTR_MAXLEN];
};
int msp430_decode_command(const ut8 *instr, struct msp430_cmd *cmd);
#endif /* MSP430_DISAS_H */

View File

@ -1254,6 +1254,7 @@ extern RAnalPlugin r_anal_plugin_sysz;
extern RAnalPlugin r_anal_plugin_sparc_cs;
extern RAnalPlugin r_anal_plugin_xcore_cs;
extern RAnalPlugin r_anal_plugin_propeller;
extern RAnalPlugin r_anal_plugin_msp430;
#ifdef __cplusplus
}
#endif

View File

@ -204,6 +204,7 @@ extern RAsmPlugin r_asm_plugin_sparc_cs;
extern RAsmPlugin r_asm_plugin_xcore_cs;
extern RAsmPlugin r_asm_plugin_spc700;
extern RAsmPlugin r_asm_plugin_propeller;
extern RAsmPlugin r_asm_plugin_msp430;
#endif
#ifdef __cplusplus

View File

@ -321,6 +321,7 @@ enum {
R_SYS_ARCH_SYSZ = 0x1000000,
R_SYS_ARCH_XCORE = 0x2000000,
R_SYS_ARCH_PROPELLER = 0x4000000,
R_SYS_ARCH_MSP430 = 0x8000000,
};
/* os */

View File

@ -29,6 +29,7 @@ asm.dcpu16
asm.m68k
asm.mips_gnu
asm.mips_cs
asm.msp430
asm.rar
asm.x86
asm.x86_olly
@ -80,6 +81,7 @@ anal.h8300
anal.cr16
anal.v850
anal.xcore_cs
anal.msp430
bin.any
bin.bios
bin.bf