1
2 """
3 The initial arm module.
4 """
5
6 import struct
7
8 import envi
9
10
12 x = 0
13 for c in s:
14 x = (x << 1) + int(c)
15 return x
16
17
18
19
20
21 IF_PSR_S = 0x100
22
23 COND_EQ = 0x0
24 COND_NE = 0x1
25 COND_CS = 0x2
26 COND_CC = 0x3
27 COND_MI = 0x4
28 COND_PL = 0x5
29 COND_VS = 0x6
30 COND_VC = 0x7
31 COND_HI = 0x8
32 COND_LO = 0x9
33 COND_GE = 0xA
34 COND_LT = 0xB
35 COND_GT = 0xC
36 COND_LE = 0xD
37 COND_AL = 0xE
38 COND_EXTENDED = 0xF
39
40 COND_EQ = 0
41 COND_NE = 1
42 COND_CS = 2
43 COND_CC = 3
44 COND_MI = 4
45 COND_PL = 5
46 COND_VS = 6
47 COND_VC = 7
48 COND_HI = 8
49 COND_LS = 9
50 COND_GE = 10
51 COND_LT = 11
52 COND_GT = 12
53 COND_LE = 13
54 COND_AL = 14
55 COND_EXTENDED = 15
56
57 cond_codes = {
58 COND_EQ:"EQ",
59 COND_NE:"NE",
60 COND_CS:"CS",
61 COND_CC:"CC",
62 COND_MI:"MI",
63 COND_PL:"PL",
64 COND_VS:"VS",
65 COND_VC:"VC",
66 COND_HI:"HI",
67 COND_LS:"LS",
68 COND_GE:"GE",
69 COND_LT:"LT",
70 COND_GT:"GT",
71 COND_LE:"LE",
72 COND_AL:"AL",
73 COND_EXTENDED:"EXTENDED",
74 }
75
76 INST_ENC_DP_IMM = 0
77 INST_ENC_MISC = 1
78
79
80 IENC_DP_IMM_SHIFT = 0
81 IENC_MISC = 1
82 IENC_DP_REG_SHIFT = 2
83 IENC_MISC1 = 3
84 IENC_MULT = 4
85 IENC_DP_IMM = 5
86 IENC_UNDEF = 6
87 IENC_MOV_IMM_STAT = 7
88 IENC_LOAD_IMM_OFF = 8
89 IENC_LOAD_REG_OFF = 9
90 IENC_MEDIA = 10
91 IENC_ARCH_UNDEF = 11
92 IENC_LOAD_MULT = 12
93 IENC_BRANCH = 13
94 IENC_COPROC_LOAD = 14
95 IENC_COPROC_DP = 15
96 IENC_COPROC_REG_XFER = 16
97 IENC_SWINT = 17
98
99
100
101
103 op1 = (opcode >> 20) & 0xff
104 a = (opcode >> 16) & 0xf
105 b = (opcode >> 12) & 0xf
106 c = (opcode >> 8) & 0xf
107 d = (opcode >> 4) & 0xf
108 e = opcode & 0xf
109 return (op1<<4)+d,(a,b,c,d,e)
110
111
112
113
114 iencmul_codes = {
115
116 binary("000000001001"): ("mul",(0,4,2), 0),
117 binary("000000011001"): ("mul",(0,4,2), IF_PSR_S),
118 binary("000000101001"): ("mla",(0,4,2,1), 0),
119 binary("000000111001"): ("mla",(0,4,2,1), IF_PSR_S),
120 binary("000001001001"): ("umaal",(1,0,4,2), 0),
121 binary("000010001001"): ("umull",(1,0,4,2), 0),
122 binary("000010011001"): ("umull",(1,0,4,2), IF_PSR_S),
123 binary("000010101001"): ("umlal",(1,0,4,2), 0),
124 binary("000010111001"): ("umlal",(1,0,4,2), IF_PSR_S),
125 binary("000011001001"): ("smull",(1,0,4,2), 0),
126 binary("000011011001"): ("smull",(1,0,4,2), IF_PSR_S),
127 binary("000011101001"): ("smlal",(1,0,4,2), 0),
128 binary("000011111001"): ("smlal",(1,0,4,2), IF_PSR_S),
129
130
131
132 binary("000100001000"): ("smlabb", (0,4,2,1), 0),
133 binary("000100001010"): ("smlatb", (0,4,2,1), 0),
134 binary("000100001100"): ("smlabt", (0,4,2,1), 0),
135 binary("000100001110"): ("smlatt", (0,4,2,1), 0),
136 binary("000100101010"): ("smulwb", (0,4,2), 0),
137 binary("000100101110"): ("smulwt", (0,4,2), 0),
138 binary("000100101000"): ("smlawb", (0,4,2), 0),
139 binary("000100101100"): ("smlawt", (0,4,2), 0),
140 binary("000101001000"): ("smlalbb", (1,0,4,2), 0),
141 binary("000101001010"): ("smlaltb", (1,0,4,2), 0),
142 binary("000101001100"): ("smlalbt", (1,0,4,2), 0),
143 binary("000101001110"): ("smlaltt", (1,0,4,2), 0),
144 binary("000101101000"): ("smulbb", (0,4,2), 0),
145 binary("000101101010"): ("smultb", (0,4,2), 0),
146 binary("000101101100"): ("smulbt", (0,4,2), 0),
147 binary("000101101110"): ("smultt", (0,4,2), 0),
148
149
150
151 binary("011100000001"): ("smuad", (0,4,2), 0),
152 binary("011100000011"): ("smuadx", (0,4,2), 0),
153 binary("011100000101"): ("smusd", (0,4,2), 0),
154 binary("011100000111"): ("smusdx", (0,4,2), 0),
155 binary("011100000001"): ("smlad", (0,4,2), 0),
156 binary("011100000011"): ("smladx", (0,4,2), 0),
157 binary("011100000101"): ("smlsd", (0,4,2), 0),
158 binary("011100000111"): ("smlsdx", (0,4,2), 0),
159 binary("011101000001"): ("smlald", (0,4,2), 0),
160 binary("011101000011"): ("smlaldx", (0,4,2), 0),
161 binary("011101000101"): ("smlsld", (0,4,2), 0),
162 binary("011101000111"): ("smlsldx", (0,4,2), 0),
163 binary("011101010001"): ("smmla", (0,4,2,1), 0),
164 binary("011101010011"): ("smmlar", (0,4,2,1), 0),
165 binary("011101011101"): ("smmls", (0,4,2,1), 0),
166 binary("011101011111"): ("smmlsr", (0,4,2,1), 0),
167 binary("011101010001"): ("smmul", (0,4,2), 0),
168 binary("011101010011"): ("smmulr", (0,4,2), 0),
169 }
170
171
172
173
174
175 dp_mnem = ("and","eor","sub","rsb","add","adc","sbc","rsc","tst","teq","cmp","cmn","orr","mov","bic","mvn"),
176 misc_mnem = ("mrs","msr","bxj")
177
179 """
180 Parse and return opcode,sflag,Rn,Rd for a standard
181 dataprocessing instruction.
182 """
183 ocode = (opval >> 21) & 0xf
184 sflag = (opval >> 20) & 0x1
185 Rn = (opval >> 16) & 0xf
186 Rd = (opval >> 12) & 0xf
187
188 return ocode,sflag,Rn,Rd
189
190
191
192
194 ocode,sflag,Rn,Rd = dpbase(opval)
195 Rm = opval & 0xf
196 shtype = (opval >> 5) & 0x3
197 shval = (opval >> 7) & 0x1f
198
199 olist = [
200 ArmOperand(OM_REG, Rn),
201 ArmOperand(OM_REG, Rd),
202 ArmOperand(OM_REG, Rm, shtype=shtype, shval=shval),
203 ]
204
205 opcode = (IENC_DP_IMM_SHIFT << 16) + ocode
206 return ArmOpcode(opcode, dp_mnem[ocode], olist)
207
210
212 ocode,sflag,Rn,Rd = dpbase(opval)
213 Rm = opval & 0xf
214 shtype = (opval >> 5) & 0x3
215 Rs = (opval >> 8) & 0xf
216
217 olist = [
218 ArmOperand(OM_REG, Rn),
219 ArmOperand(OM_REG, Rd),
220 ArmOperand(OM_REG, Rm, oflags=OFLAG_SHIFT_REG, shtype=shtype, shval=shval),
221 ]
222
223 opcode = (IENC_DP_IMM_SHIFT << 16) + ocode
224 return ArmOpcode(opcode, dp_mnem[ocode], olist)
225
228
240
242 ocode,sflag,Rn,Rd = dpbase(opval)
243 imm = opval & 0xff
244 rot = (opval >> 8) & 0xf
245
248
251
254
257
260
263
266
269
272
275
278
281
282
283
284
285 ienc_parsers = (
286 p_dp_imm_shift,
287 p_misc,
288 p_dp_reg_shift,
289 p_misc1,
290 p_mult,
291 p_dp_imm,
292 p_undef,
293 p_mov_imm_stat,
294 p_load_imm_off,
295 p_load_reg_off,
296 p_media,
297 p_arch_undef,
298 p_load_mult,
299 p_branch,
300 p_coproc_load,
301 p_coproc_dp,
302 p_coproc_reg_xfer,
303 p_swint,
304 )
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321 s_0_table = (
322
323 (binary("00000001100100000000000000010000"), binary("00000001000000000000000000000000"), IENC_MISC),
324 (binary("00000000000000000000000000010000"), binary("00000000000000000000000000000000"), IENC_DP_IMM_SHIFT),
325 (binary("00000000000000000000000010010000"), binary("00000000000000000000000010010000"), IENC_MULT),
326 (binary("00000001100000000000000010010000"), binary("00000001000000000000000000010000"), IENC_MISC1),
327 (binary("00000000000000000000000010010000"), binary("00000000000000000000000000010000"), IENC_DP_REG_SHIFT),
328 )
329
330 s_1_table = (
331 (binary("00000001100110000000000000000000"), binary("00000001000000000000000000000000"), IENC_UNDEF),
332 (binary("00000001100110000000000000000000"), binary("00000001001000000000000000000000"), IENC_MOV_IMM_STAT),
333 (0,0, IENC_DP_IMM),
334 )
335
336 s_3_table = (
337 (binary("00000001111100000000000011110000"),binary("00000001111100000000000011110000"), IENC_ARCH_UNDEF),
338 (binary("00000000000000000000000000010000"),binary("00000000000000000000000000010000"), IENC_MEDIA),
339 (0,0, IENC_LOAD_REG_OFF),
340 )
341
342 s_7_table = (
343 (binary("00000001000000000000000000000000"),binary("00000001000000000000000000000000"), IENC_SWINT),
344 (binary("00000001000000000000000000010000"),binary("00000000000000000000000000010000"), IENC_COPROC_REG_XFER),
345 (0, 0, IENC_COPROC_DP),
346 )
347
348
349 inittable = [
350 (None, s_0_table),
351 (None, s_1_table),
352 (IENC_LOAD_IMM_OFF, None),
353 (None, s_3_table),
354 (IENC_LOAD_MULT, None),
355 (IENC_BRANCH, None),
356 (IENC_COPROC_LOAD, None),
357 (None, s_7_table),
358 ]
359
360 OFLAG_SHIFT_REG = 1
361
362
363 S_LSL = 0
364 S_LSR = 1
365 S_ASR = 2
366 S_ROR = 3
367 S_RRX = 4
368
369 shift_names = ["lsl", "lsr", "asr", "ror", "rrx"]
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 endian_names = ("LE","BE")
387
389
393
395 x = [self.mnem, cond_codes.get(self.cond)]
396
397 for o in self.opers:
398 x.append(repr(o))
399 return " ".join(x)
400
401
402 IF_PSR_S = 0x100
403
404 OM_IMM = 0
405 OM_REG = 1
406 OM_REG_MULT = 2
407 OM_PSR = 3
408 OM_ENDIAN = 4
409 OM_COPROC_OP = 5
410
412 - def __init__(self, mode, val, oflags=0, shtype=None, shval=None):
413 envi.Operand.__init__(self, mode)
414 self.val = val
415 self.oflags = oflags
416 self.shval = shval
417 self.shtype = shtype
418
420 if not envi.Operand.__eq__(self, oper):
421 return False
422 if self.val != oper.val:
423 return False
424 if self.oflags != oper.oflags:
425 return False
426 if self.shval != oper.shval:
427 return False
428 if self.shtype != oper.shtype:
429 return False
430 return True
431
453
455
458
460 opval = struct.unpack("<L", bytes[offset:offset+4])[0]
461
462 cond = opval >> 28
463
464 if cond == COND_EXTENDED:
465 return "FIXME - make extended opcode parser"
466
467
468 encfam = (opval >> 25) & 0x7
469 enc,nexttab = inittable[encfam]
470 if nexttab != None:
471 for mask,val,penc in nexttab:
472 if (opval & mask) == val:
473 enc = penc
474 break
475
476
477 if enc == None:
478 raise InvalidInstruction("omg")
479
480
481
482
483
484 op = ienc_parsers[enc](opval)
485 op.cond = cond
486
487 return op
488
489 a = ArmModule()
490
491
492 print repr(a.makeOpcode("\x92\x10\x93\x00", 0))
493 print repr(a.makeOpcode("\x04\x30\x83\xe2", 0))
494