1 #include <string.h>
2 #include <r_types.h>
3 #include <r_lib.h>
4 #include <r_asm.h>
5 #include <r_anal.h>
6 #include <r_util.h>
7
8 #include <msp430_disas.h>
9
msp430_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)10 static int msp430_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
11 int ret;
12 struct msp430_cmd cmd;
13
14 memset (&cmd, 0, sizeof (cmd));
15 //op->id = ???;
16 op->size = -1;
17 op->nopcode = 1;
18 op->type = R_ANAL_OP_TYPE_UNK;
19 op->family = R_ANAL_OP_FAMILY_CPU;
20
21 ret = op->size = msp430_decode_command (buf, len, &cmd);
22
23 if (ret < 0) {
24 return ret;
25 }
26
27 op->addr = addr;
28
29 switch (cmd.type) {
30 case MSP430_ONEOP:
31 switch (cmd.opcode) {
32 case MSP430_RRA:
33 case MSP430_RRC:
34 op->type = R_ANAL_OP_TYPE_ROR; break;
35 case MSP430_PUSH:
36 op->type = R_ANAL_OP_TYPE_PUSH; break;
37 case MSP430_CALL:
38 op->type = R_ANAL_OP_TYPE_CALL;
39 op->fail = addr + op->size;
40 op->jump = r_read_at_le16 (buf, 2);
41 break;
42 case MSP430_RETI:
43 op->type = R_ANAL_OP_TYPE_RET; break;
44 }
45 break;
46 case MSP430_TWOOP:
47 switch (cmd.opcode) {
48 case MSP430_BIT:
49 case MSP430_BIC:
50 case MSP430_BIS:
51 case MSP430_MOV:
52 op->type = R_ANAL_OP_TYPE_MOV;
53 if ((cmd.instr)[0] == 'b' && (cmd.instr)[1] == 'r') {
54 // Emulated branch instruction, moves source operand to PC register.
55 op->type = R_ANAL_OP_TYPE_UJMP;
56 }
57 break;
58 case MSP430_DADD:
59 case MSP430_ADDC:
60 case MSP430_ADD: op->type = R_ANAL_OP_TYPE_ADD; break;
61 case MSP430_SUBC:
62 case MSP430_SUB: op->type = R_ANAL_OP_TYPE_SUB; break;
63 case MSP430_CMP: op->type = R_ANAL_OP_TYPE_CMP; break;
64 case MSP430_XOR: op->type = R_ANAL_OP_TYPE_XOR; break;
65 case MSP430_AND: op->type = R_ANAL_OP_TYPE_AND; break;
66 }
67 break;
68 case MSP430_JUMP:
69 if (cmd.jmp_cond == MSP430_JMP) {
70 op->type = R_ANAL_OP_TYPE_JMP;
71 } else {
72 op->type = R_ANAL_OP_TYPE_CJMP;
73 }
74 op->jump = addr + cmd.jmp_addr;
75 op->fail = addr + 2;
76 break;
77 case MSP430_INV:
78 op->type = R_ANAL_OP_TYPE_ILL;
79 break;
80 default:
81 op->type = R_ANAL_OP_TYPE_UNK;
82 }
83
84 return ret;
85 }
86
87 RAnalPlugin r_anal_plugin_msp430 = {
88 .name = "msp430",
89 .desc = "TI MSP430 code analysis plugin",
90 .license = "LGPL3",
91 .arch = "msp430",
92 .bits = 16,
93 .op = msp430_op,
94 };
95