1
2 import envi.bits as e_bits
3 import envi.bintree as e_btree
4
5 from envi.bits import binary
6
7 from envi.archs.arm.armdisasm import *
8
9 thumb_32 = [
10 binary('11101'),
11 binary('11110'),
12 binary('11111'),
13 ]
14
15
16 O_REG = 0
17 O_IMM = 1
18
19 OperType = (
20 ArmRegOper,
21 ArmImmOper,
22 )
24 return (value >> shval) & mask
25
28 self.operdef = operdef
29
31 ret = []
32 for otype, shval, mask in self.operdef:
33 oval = shmaskval(value, shval, mask)
34 oper = OperType[otype]((value >> shval) & mask)
35 ret.append( oper )
36 return ret
37
38 imm5_rm_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 6, 0x1f))
39 rm_rn_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_REG, 6, 0x7))
40 imm3_rn_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 6, 0x7))
41 imm8_rd = simpleops((O_REG, 8, 0x7), (O_IMM, 0, 0xff))
42 rm_rd = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
43 rn_rdm = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
44 rm_rdn = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7))
45 rm_rd_imm0 = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_IMM, 0, 0))
46 rm4_shift3 = simpleops((O_REG, 3, 0xf))
47 rm_rn_rt = simpleops((O_REG, 0, 0x7), (O_REG, 3, 0x7), (O_REG, 6, 0x7))
48 imm8 = simpleops((O_IMM, 8, 0xff))
49 imm11 = simpleops((O_IMM, 11, 0x7ff))
50
51 sh4_imm1 = simpleops((O_IMM, 3, 0x1))
52
59
67
75
83
91
98
100 rd = shmaskval(value, 8, 0x7)
101 reg_list = value & 0xff
102 oper0 = ArmRegOper(rd)
103 oper1 = ArmRegListOper(reg_list)
104 flags = 1<<11
105 return oper0,oper1
106
113
120
121
122
123
124
125
126 thumb_table = [
127 ('00000', ( 0,'lsl', imm5_rm_rd, 0)),
128 ('00001', ( 1,'lsr', imm5_rm_rd, 0)),
129 ('00010', ( 2,'asr', imm5_rm_rd, 0)),
130 ('0001100', ( 3,'add', rm_rn_rd, 0)),
131 ('0001101', ( 4,'sub', rm_rn_rd, 0)),
132 ('0001110', ( 5,'add', imm3_rn_rd, 0)),
133 ('0001111', ( 6,'sub', imm3_rn_rd, 0)),
134 ('00100', ( 7,'mov', imm8_rd, 0)),
135 ('00101', ( 8,'cmp', imm8_rd, 0)),
136 ('00110', ( 9,'add', imm8_rd, 0)),
137 ('00111', (10,'sub', imm8_rd, 0)),
138
139 ('0100000000', (11,'and', rm_rdn, 0)),
140 ('0100000001', (12,'eor', rm_rdn, 0)),
141 ('0100000010', (13,'lsl', rm_rdn, 0)),
142 ('0100000011', (14,'lsr', rm_rdn, 0)),
143 ('0100000100', (15,'asr', rm_rdn, 0)),
144 ('0100000101', (16,'adc', rm_rdn, 0)),
145 ('0100000110', (17,'sbc', rm_rdn, 0)),
146 ('0100000111', (18,'ror', rm_rdn, 0)),
147 ('0100001000', (19,'tst', rm_rd, 0)),
148 ('0100001001', (20,'rsb', rm_rd_imm0, 0)),
149 ('0100001010', (21,'cmp', rm_rd, 0)),
150 ('0100001011', (22,'cmn', rm_rd, 0)),
151 ('0100001100', (23,'orr', rm_rdn, 0)),
152 ('0100001101', (24,'mul', rn_rdm, 0)),
153 ('0100001110', (25,'bic', rm_rdn, 0)),
154 ('0100001111', (26,'mvn', rm_rd, 0)),
155
156 ('0100010000', (27,'add', d1_rm4_rd3, 0)),
157 ('0100010001', (28,'add', d1_rm4_rd3, 0)),
158 ('010001001', (29,'add', d1_rm4_rd3, 0)),
159 ('0100010101', (30,'cmp', d1_rm4_rd3, 0)),
160 ('010001011', (31,'cmp', d1_rm4_rd3, 0)),
161 ('0100011000', (32,'mov', d1_rm4_rd3, 0)),
162 ('0100011001', (33,'mov', d1_rm4_rd3, 0)),
163 ('0100011010', (34,'mov', d1_rm4_rd3, 0)),
164 ('010001110', (35,'bx', rm4_shift3, 0)),
165 ('010001111', (36,'blx', rm4_shift3, 0)),
166
167 ('01001', (37,'ldr', rt_pc_imm8, 0)),
168
169 ('0101000', (38,'str', rm_rn_rt, 0)),
170 ('0101001', (39,'strh', rm_rn_rt, 0)),
171 ('0101010', (40,'strb', rm_rn_rt, 0)),
172 ('0101011', (41,'ldrsb', rm_rn_rt, 0)),
173 ('0101100', (42,'ldr', rm_rn_rt, 0)),
174 ('0101101', (43,'ldrh', rm_rn_rt, 0)),
175 ('0101110', (44,'ldrb', rm_rn_rt, 0)),
176 ('0101111', (45,'ldrsh', rm_rn_rt, 0)),
177 ('01100', (46,'str', imm5_rn_rt, 0)),
178 ('01101', (47,'ldr', imm5_rn_rt, 0)),
179 ('01110', (48,'strb', imm5_rn_rt, 0)),
180 ('01111', (49,'ldrb', imm5_rn_rt, 0)),
181 ('10000', (50,'strh', imm5_rn_rt, 0)),
182 ('10001', (51,'ldrh', imm5_rn_rt, 0)),
183 ('10010', (52,'str', imm5_rn_rt, 0)),
184 ('10011', (53,'ldr', imm5_rn_rt, 0)),
185
186 ('10100', (54,'add', rd_pc_imm8, 0)),
187
188 ('10101', (55,'add', rd_sp_imm8, 0)),
189
190 ('10110110010', (56,'setend', sh4_imm1, 0)),
191 ('10110110011', (57,'cps', simpleops(),0)),
192 ('1011101000', (58,'rev', rn_rdm, 0)),
193 ('1011101001', (59,'rev16', rn_rdm, 0)),
194 ('1011101011', (60,'revsh', rn_rdm, 0)),
195 ('101100000', (61,'add', sp_sp_imm7, 0)),
196 ('101100001', (62,'sub', sp_sp_imm7, 0)),
197 ('10111110', (63,'bkpt', imm8, 0)),
198
199 ('11000', (64,'stmia', rm_reglist, 0x800)),
200 ('11001', (65,'ldmia', rm_reglist, 0x800)),
201
202 ('11010000', (66,'b', imm8, 0)),
203 ('11010001', (67,'bn', imm8, 0)),
204 ('11010010', (68,'bz', imm8, 0)),
205 ('11010011', (69,'bnz', imm8, 0)),
206 ('11010100', (70,'bc', imm8, 0)),
207 ('11010101', (71,'bnc', imm8, 0)),
208 ('11010100', (72,'bzc', imm8, 0)),
209 ('11010111', (73,'bnzc', imm8, 0)),
210 ('11011000', (74,'bv', imm8, 0)),
211 ('11011001', (75,'bnv', imm8, 0)),
212 ('11011010', (76,'bzv', imm8, 0)),
213 ('11011011', (77,'bnzv', imm8, 0)),
214 ('11011100', (78,'bcv', imm8, 0)),
215 ('11011101', (79,'bncv', imm8, 0)),
216 ('11011110', (80,'bzcv', imm8, 0)),
217 ('11011111', (81,'bnzcv', imm8, 0)),
218
219 ('11011111', (82,'swi', imm8, 0)),
220 ('11100', (83,'b', imm11, 0)),
221 ('11101', (84,'blx', imm11, 0)),
222 ('11110', (85,'bl', imm11, 0)),
223 ('11111', (86,'blx', imm11, 0)),
224 ]
225
226 ttree = e_btree.BinaryTree()
227 for binstr, opinfo in thumb_table:
228 ttree.addBinstr(binstr, opinfo)
229
230 thumb32mask = binary('11111')
231 thumb32min = binary('11100')
232
234 '''
235 Take a 16 bit integer (opcode) value and determine
236 if it is really the first 16 bits of a 32 bit
237 instruction.
238 '''
239 bval = val >> 11
240 return (bval & thumb32mask) > thumb32min
241
242
245
247
248 - def disasm(self, bytes, offset, va, trackMode=True):
249 val, = struct.unpack("H", bytes[offset:offset+2])
250 opcode, mnem, opermkr, flags = ttree.getInt(val, 16)
251 olist = opermkr(va, val)
252 op = ThumbOpcode(va, opcode, mnem, 0xe, 2, olist, flags)
253 return op
254