1 /* Capstone Disassembly Engine */
2 /* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
3 
4 #include <stdio.h>
5 #include <capstone/capstone.h>
6 
7 void print_string_hex(char *comment, unsigned char *str, size_t len);
8 
9 static const char *s_access[] = {
10 	"UNCHANGED", "READ", "WRITE", "READ | WRITE",
11 };
12 
print_read_write_regs(csh handle,cs_detail * detail)13 void print_read_write_regs(csh handle, cs_detail *detail)
14 {
15 	int i;
16 
17 	if (detail->regs_read_count > 0) {
18 		printf("\treading from regs: ");
19 
20 		for (i = 0; i < detail->regs_read_count; ++i) {
21 			if (i > 0)
22 				printf(", ");
23 
24 			printf("%s", cs_reg_name(handle, detail->regs_read[i]));
25 		}
26 
27 		printf("\n");
28 	}
29 
30 	if (detail->regs_write_count > 0) {
31 		printf("\twriting to regs: ");
32 
33 		for (i = 0; i < detail->regs_write_count; ++i) {
34 			if (i > 0)
35 				printf(", ");
36 
37 			printf("%s", cs_reg_name(handle,
38 					detail->regs_write[i]));
39 		}
40 
41 		printf("\n");
42 	}
43 }
44 
print_insn_detail_m680x(csh handle,cs_insn * insn)45 void print_insn_detail_m680x(csh handle, cs_insn *insn)
46 {
47 	cs_detail *detail = insn->detail;
48 	cs_m680x *m680x = NULL;
49 	int i;
50 
51 	// detail can be NULL on "data" instruction if SKIPDATA option is
52 	// turned ON
53 	if (detail == NULL)
54 		return;
55 
56 	m680x = &detail->m680x;
57 
58 	if (m680x->op_count)
59 		printf("\top_count: %u\n", m680x->op_count);
60 
61 	for (i = 0; i < m680x->op_count; i++) {
62 		cs_m680x_op *op = &(m680x->operands[i]);
63 		const char *comment;
64 
65 		switch ((int)op->type) {
66 		default:
67 			break;
68 
69 		case M680X_OP_REGISTER:
70 			comment = "";
71 
72 			if ((i == 0 && m680x->flags & M680X_FIRST_OP_IN_MNEM) ||
73 				(i == 1 && m680x->flags &
74 					M680X_SECOND_OP_IN_MNEM))
75 				comment = " (in mnemonic)";
76 
77 			printf("\t\toperands[%u].type: REGISTER = %s%s\n", i,
78 				cs_reg_name(handle, op->reg), comment);
79 			break;
80 
81 		case M680X_OP_CONSTANT:
82 			printf("\t\toperands[%u].type: CONSTANT = %u\n", i,
83 				op->const_val);
84 			break;
85 
86 		case M680X_OP_IMMEDIATE:
87 			printf("\t\toperands[%u].type: IMMEDIATE = #%d\n", i,
88 				op->imm);
89 			break;
90 
91 		case M680X_OP_DIRECT:
92 			printf("\t\toperands[%u].type: DIRECT = 0x%02X\n", i,
93 				op->direct_addr);
94 			break;
95 
96 		case M680X_OP_EXTENDED:
97 			printf("\t\toperands[%u].type: EXTENDED %s = 0x%04X\n",
98 				i, op->ext.indirect ? "INDIRECT" : "",
99 				op->ext.address);
100 			break;
101 
102 		case M680X_OP_RELATIVE:
103 			printf("\t\toperands[%u].type: RELATIVE = 0x%04X\n", i,
104 				op->rel.address);
105 			break;
106 
107 		case M680X_OP_INDEXED:
108 			printf("\t\toperands[%u].type: INDEXED%s\n", i,
109 				(op->idx.flags & M680X_IDX_INDIRECT) ?
110 				" INDIRECT" : "");
111 
112 			if (op->idx.base_reg != M680X_REG_INVALID)
113 				printf("\t\t\tbase register: %s\n",
114 					cs_reg_name(handle, op->idx.base_reg));
115 
116 			if (op->idx.offset_reg != M680X_REG_INVALID)
117 				printf("\t\t\toffset register: %s\n",
118 					cs_reg_name(handle, op->idx.offset_reg));
119 
120 			if ((op->idx.offset_bits != 0) &&
121 				(op->idx.offset_reg == M680X_REG_INVALID) &&
122 				!op->idx.inc_dec) {
123 				printf("\t\t\toffset: %d\n", op->idx.offset);
124 
125 				if (op->idx.base_reg == M680X_REG_PC)
126 					printf("\t\t\toffset address: 0x%X\n",
127 						op->idx.offset_addr);
128 
129 				printf("\t\t\toffset bits: %u\n",
130 					op->idx.offset_bits);
131 			}
132 
133 			if (op->idx.inc_dec) {
134 				const char *post_pre = op->idx.flags &
135 					M680X_IDX_POST_INC_DEC ? "post" : "pre";
136 				const char *inc_dec = (op->idx.inc_dec > 0) ?
137 					"increment" : "decrement";
138 
139 				printf("\t\t\t%s %s: %d\n", post_pre, inc_dec,
140 					abs(op->idx.inc_dec));
141 			}
142 
143 			break;
144 		}
145 
146 		if (op->size != 0)
147 			printf("\t\t\tsize: %u\n", op->size);
148 
149 		if (op->access != CS_AC_INVALID)
150 			printf("\t\t\taccess: %s\n", s_access[op->access]);
151 	}
152 
153 	print_read_write_regs(handle, detail);
154 }
155 
156