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