1 import sys
2 import struct
3 import traceback
4
5 import envi
6 import envi.bits as e_bits
7 from envi.bits import binary
8
9 from envi.archs.arm.const import *
10 from envi.archs.arm.regs import *
11
12
13
14
15
16
17
18
19
20
21
22
23
25 op1 = (opcode >> 20) & 0xff
26 a = (opcode >> 16) & 0xf
27 b = (opcode >> 12) & 0xf
28 c = (opcode >> 8) & 0xf
29 d = (opcode >> 4) & 0xf
30 e = opcode & 0xf
31 return (op1<<4)+d,(a,b,c,d,e)
32
33
39
40
41
42
43 iencmul_codes = {
44
45 binary("000000001001"): ("mul",(0,4,2), 0),
46 binary("000000011001"): ("mul",(0,4,2), IF_PSR_S),
47 binary("000000101001"): ("mla",(0,4,2,1), 0),
48 binary("000000111001"): ("mla",(0,4,2,1), IF_PSR_S),
49 binary("000001001001"): ("umaal",(1,0,4,2), 0),
50 binary("000010001001"): ("umull",(1,0,4,2), 0),
51 binary("000010011001"): ("umull",(1,0,4,2), IF_PSR_S),
52 binary("000010101001"): ("umlal",(1,0,4,2), 0),
53 binary("000010111001"): ("umlal",(1,0,4,2), IF_PSR_S),
54 binary("000011001001"): ("smull",(1,0,4,2), 0),
55 binary("000011011001"): ("smull",(1,0,4,2), IF_PSR_S),
56 binary("000011101001"): ("smlal",(1,0,4,2), 0),
57 binary("000011111001"): ("smlal",(1,0,4,2), IF_PSR_S),
58
59
60
61 binary("000100001000"): ("smlabb", (0,4,2,1), 0),
62 binary("000100001010"): ("smlatb", (0,4,2,1), 0),
63 binary("000100001100"): ("smlabt", (0,4,2,1), 0),
64 binary("000100001110"): ("smlatt", (0,4,2,1), 0),
65 binary("000100101010"): ("smulwb", (0,4,2), 0),
66 binary("000100101110"): ("smulwt", (0,4,2), 0),
67 binary("000100101000"): ("smlawb", (0,4,2), 0),
68 binary("000100101100"): ("smlawt", (0,4,2), 0),
69 binary("000101001000"): ("smlalbb", (1,0,4,2), 0),
70 binary("000101001010"): ("smlaltb", (1,0,4,2), 0),
71 binary("000101001100"): ("smlalbt", (1,0,4,2), 0),
72 binary("000101001110"): ("smlaltt", (1,0,4,2), 0),
73 binary("000101101000"): ("smulbb", (0,4,2), 0),
74 binary("000101101010"): ("smultb", (0,4,2), 0),
75 binary("000101101100"): ("smulbt", (0,4,2), 0),
76 binary("000101101110"): ("smultt", (0,4,2), 0),
77
78
79
80 binary("011100000001"): ("smuad", (0,4,2), 0),
81 binary("011100000011"): ("smuadx", (0,4,2), 0),
82 binary("011100000101"): ("smusd", (0,4,2), 0),
83 binary("011100000111"): ("smusdx", (0,4,2), 0),
84 binary("011100000001"): ("smlad", (0,4,2), 0),
85 binary("011100000011"): ("smladx", (0,4,2), 0),
86 binary("011100000101"): ("smlsd", (0,4,2), 0),
87 binary("011100000111"): ("smlsdx", (0,4,2), 0),
88 binary("011101000001"): ("smlald", (0,4,2), 0),
89 binary("011101000011"): ("smlaldx", (0,4,2), 0),
90 binary("011101000101"): ("smlsld", (0,4,2), 0),
91 binary("011101000111"): ("smlsldx", (0,4,2), 0),
92 binary("011101010001"): ("smmla", (0,4,2,1), 0),
93 binary("011101010011"): ("smmlar", (0,4,2,1), 0),
94 binary("011101011101"): ("smmls", (0,4,2,1), 0),
95 binary("011101011111"): ("smmlsr", (0,4,2,1), 0),
96 binary("011101010001"): ("smmul", (0,4,2), 0),
97 binary("011101010011"): ("smmulr", (0,4,2), 0),
98 }
99
101 return (num&0xffffffff) << shval
103 return (num&0xffffffff) >> shval
107 return (((num&0xffffffff) >> shval) | (num<< (32-shval))) & 0xffffffff
108 -def sh_rrx(num,shval, emu=None):
109 half1 = (num&0xffffffff) >> shval
110 half2 = num<<(33-shval)
111 newC = (num>>(shval-1)) & 1
112 if emu != None:
113 flags = emu.getFlags()
114 oldC = (flags>>PSR_C) & 1
115 emu.setFlags(flags & PSR_C_mask | newC)
116 else:
117 oldC = 0
118 retval = (half1 | half2 | (oldC << (32-shval))) & 0xffffffff
119 return retval
120
121 shifters = (
122 sh_lsl,
123 sh_lsr,
124 sh_asr,
125 sh_ror,
126 sh_rrx,
127 )
128
129
130
131
132
133
134 dp_mnem = ("and","eor","sub","rsb","add","adc","sbc","rsc","tst","teq","cmp","cmn","orr","mov","bic","mvn",)
135
136
137 dp_noRn = (13,15)
138 dp_noRd = (8,9,10,11)
139
140
141
142
144 """
145 Parse and return opcode,sflag,Rn,Rd for a standard
146 dataprocessing instruction.
147 """
148 ocode = (opval >> 21) & 0xf
149 sflag = (opval >> 20) & 0x1
150 Rn = (opval >> 16) & 0xf
151 Rd = (opval >> 12) & 0xf
152
153 return ocode,sflag,Rn,Rd
154
155
156
157
159 ocode,sflag,Rn,Rd = dpbase(opval)
160 Rm = opval & 0xf
161 shtype = (opval >> 5) & 0x3
162 shval = (opval >> 7) & 0x1f
163
164 if ocode in dp_noRn:
165 olist = (
166 ArmRegOper(Rd),
167 ArmRegShiftImmOper(Rm, shtype, shval),
168 )
169 elif ocode in dp_noRd:
170 olist = (
171 ArmRegOper(Rn),
172 ArmRegShiftImmOper(Rm, shtype, shval),
173 )
174 else:
175 olist = (
176 ArmRegOper(Rd),
177 ArmRegOper(Rn),
178 ArmRegShiftImmOper(Rm, shtype, shval),
179 )
180
181 opcode = (IENC_DP_IMM_SHIFT << 16) + ocode
182 if sflag > 0:
183 iflags = IF_PSR_S
184 else:
185 iflags = 0
186 return (opcode, dp_mnem[ocode], olist, iflags)
187
188
189 qop_mnem = ('qadd','qsub','qdadd','qdsub')
190 smla_mnem = ('smlabb','smlabt','smlatb','smlatt',)
191 smlal_mnem = ('smlalbb','smlalbt','smlaltb','smlaltt',)
192 smul_mnem = ('smulbb','smulbt','smultb','smultt',)
193 smlaw_mnem = ('smlawb','smlawt',)
194 smlaw_mnem = ('smulwb','smulwt',)
195
197
198 if opval & 0x0fc00000 == 0x01000000:
199 opcode = (IENC_MISC << 16) + 1
200 mnem = 'mrs'
201 r = (opval>>22) & 1
202 Rd = (opval>>12) & 0xf
203 olist = (
204 ArmRegOper(Rd),
205 ArmPgmStatRegOper(r),
206 )
207 elif opval & 0x0fc000f0 == 0x01200000:
208 opcode = (IENC_MISC << 16) + 2
209 mnem = 'msr'
210 r = (opval>>22) & 1
211 Rd = (opval>>12) & 0xf
212 olist = (
213 ArmPgmStatRegOper(r),
214 ArmRegOper(Rd),
215 )
216 elif opval & 0x0ff000f0 == 0x01200020:
217 opcode = (IENC_MISC << 16) + 5
218 mnem = 'bxj'
219 Rm = opval & 0xf
220 olist = ( ArmRegOper(Rm), )
221
222 elif opval & 0x0ff00090 == 0x01000080:
223 opcode = (IENC_MISC << 16) + 9
224 xy = (opval>>5)&3
225 mnem = smla_mnem[xy]
226 Rd = (opval>>16) & 0xf
227 Rn = (opval>>12) & 0xf
228 Rs = (opval>>8) & 0xf
229 Rm = opval & 0xf
230 olist = (
231 ArmRegOper(Rd),
232 ArmRegOper(Rm),
233 ArmRegOper(Rs),
234 ArmRegOper(Rn),
235 )
236 elif opval & 0x0ff000b0 == 0x01200080:
237 opcode = (IENC_MISC << 16) + 10
238 y = (opval>>6)&1
239 mnem = smlaw_mnem[y]
240 Rd = (opval>>16) & 0xf
241 Rn = (opval>>12) & 0xf
242 Rs = (opval>>8) & 0xf
243 Rm = opval & 0xf
244 olist = (
245 ArmRegOper(Rd),
246 ArmRegOper(Rm),
247 ArmRegOper(Rs),
248 ArmRegOper(Rn),
249 )
250 elif opval & 0x0ff000b0 == 0x012000a0:
251 opcode = (IENC_MISC << 16) + 11
252 y = (opval>>6)&1
253 mnem = smulw_mnem[y]
254 Rd = (opval>>16) & 0xf
255 Rs = (opval>>8) & 0xf
256 Rm = opval & 0xf
257 olist = (
258 ArmRegOper(Rd),
259 ArmRegOper(Rm),
260 ArmRegOper(Rs),
261 )
262 elif opval & 0x0ff00090 == 0x01400080:
263 opcode = (IENC_MISC << 16) + 12
264 xy = (opval>>5)&3
265 mnem = smlal_mnem[xy]
266 Rdhi = (opval>>16) & 0xf
267 Rdlo = (opval>>12) & 0xf
268 Rs = (opval>>8) & 0xf
269 Rm = opval & 0xf
270 olist = (
271 ArmRegOper(Rdlo),
272 ArmRegOper(Rdhi),
273 ArmRegOper(Rs),
274 ArmRegOper(Rn),
275 )
276 elif opval & 0x0ff00090 == 0x01600080:
277 opcode = (IENC_MISC << 16) + 13
278 xy = (opval>>5)&3
279 mnem = smulxy_mnem[xy]
280 Rd = (opval>>16) & 0xf
281 Rs = (opval>>8) & 0xf
282 Rm = opval & 0xf
283 olist = (
284 ArmRegOper(Rd),
285 ArmRegOper(Rm),
286 ArmRegOper(Rs),
287 )
288 mnem = 'smul'
289
290
291 else:
292 raise Exception("p_misc: invalid instruction: %.8x:\t%.8x"%(va,opval))
293 opcode = IENC_UNDEF
294 mnem = "undefined instruction"
295 olist = ()
296
297 return (opcode, mnem, olist, 0)
298
299
300
301
302
304
305
306
307
308
309
310 if opval & 0x0ff000f0 == 0x01200010:
311 opcode = INS_BX
312 mnem = 'bx'
313 Rm = opval & 0xf
314 olist = ( ArmRegOper(Rm), )
315
316 elif opval & 0x0ff000f0 == 0x01600010:
317 opcode = (IENC_MISC << 16) + 4
318 mnem = 'clz'
319 Rd = (opval>>12) & 0xf
320 Rm = opval & 0xf
321 olist = (
322 ArmRegOper(Rd),
323 ArmRegOper(Rm),
324 )
325 elif opval & 0x0ff000f0 == 0x01200030:
326
327 opcode = INS_BLX
328 mnem = 'blx'
329 Rm = opval & 0xf
330 olist = ( ArmRegOper(Rm), )
331
332 elif opval & 0x0f9000f0 == 0x01000050:
333 opcode = (IENC_MISC << 16) + 7
334 qop = (opval>>21)&3
335 mnem = qop_mnem[qop]
336 Rn = (opval>>16) & 0xf
337 Rd = (opval>>12) & 0xf
338 Rm = opval & 0xf
339 olist = (
340 ArmRegOper(Rd),
341 ArmRegOper(Rm),
342 ArmRegOper(Rn),
343 )
344
345 elif opval & 0x0ff000f0 == 0x01200070:
346 opcode = (IENC_MISC << 16) + 8
347 mnem = 'bkpt'
348 immed = ((opval>>4)&0xfff0) + (opval&0xf)
349 olist = ( ArmImmOper(immed), )
350
351 else:
352 raise Exception("p_misc1: invalid instruction: %.8x:\t%.8x"%(va,opval))
353
354 return (opcode, mnem, olist, 0)
355
356
357
358 swap_mnem = ("swp","swpb",)
359 strex_mnem = ("strex","ldrex",)
360
361
362
363 strh_mnem = (("str",IF_H),("ldr",IF_H),)
364 ldrs_mnem = (("ldr",IF_S|IF_H),("ldr",IF_S|IF_B),)
365 ldrd_mnem = (("ldr",IF_D),("str",IF_D),)
367 pubwl = (opval>>20) & 0x1f
368 Rn = (opval>>16) & 0xf
369 Rd = (opval>>12) & 0xf
370 Rs = (opval>>8) & 0xf
371 op1 = (opval>>5) & 0x3
372 Rm = opval & 0xf
373 iflags = 0
374
375 if opval&0x0fb000f0==0x01000090:
376 idx = (pubwl>>2)&1
377 opcode = (IENC_EXTRA_LOAD << 16) + idx
378 mnem = swap_mnem[idx]
379 olist = (
380 ArmRegOper(Rd),
381 ArmRegOper(Rm),
382 ArmImmOffsetOper(Rn, 0, va),
383 )
384 elif opval&0x0fe000f0==0x01800090:
385 idx = pubwl&1
386 opcode = (IENC_EXTRA_LOAD << 16) + 2 + idx
387 mnem = strex_mnem[idx]
388 olist = (
389 ArmRegOper(Rd),
390 ArmRegOper(Rm),
391 ArmRegOper(Rn),
392 )
393 elif opval&0x0e4000f0==0x000000b0:
394 idx = pubwl&1
395 opcode = (IENC_EXTRA_LOAD << 16) + 4 + idx
396 mnem,iflags = strh_mnem[idx]
397 olist = (
398 ArmRegOper(Rd),
399 ArmRegOffsetOper(Rn, Rm, va, pubwl),
400 )
401 elif opval&0x0e4000f0==0x004000b0:
402 idx = pubwl&1
403 opcode = (IENC_EXTRA_LOAD << 16) + 6 + idx
404 mnem,iflags = strh_mnem[idx]
405 olist = (
406 ArmRegOper(Rd),
407 ArmImmOffsetOper(Rn,(Rs<<4)+Rm, va),
408 )
409 elif opval&0x0e4000d0==0x004000d0:
410 idx = (opval>>5)&1
411 opcode = (IENC_EXTRA_LOAD << 16) + 8 + idx
412 mnem,iflags = ldrs_mnem[idx]
413 olist = (
414 ArmRegOper(Rd),
415 ArmImmOffsetOper(Rn, (Rs<<4)+Rm, va, pubwl),
416 )
417 elif opval&0x0e4000d0==0x000000d0:
418 idx = (opval>>5)&1
419 opcode = (IENC_EXTRA_LOAD << 16) + 10 + idx
420 mnem,iflags = ldrs_mnem[idx]
421 olist = (
422 ArmRegOper(Rd),
423 ArmRegOffsetOper(Rn, Rm, va, pubwl),
424 )
425 elif opval&0x0e5000d0==0x000000d0:
426 idx = (opval>>5)&1
427 opcode = (IENC_EXTRA_LOAD << 16) + 12 + idx
428 mnem,iflags = ldrd_mnem[idx]
429 olist = (
430 ArmRegOper(Rd),
431 ArmRegOffsetOper(Rn, Rm, va, pubwl),
432 )
433 elif opval&0x0e5000d0==0x004000d0:
434 idx = (opval>>5)&1
435 opcode = (IENC_EXTRA_LOAD << 16) + 14 + idx
436 mnem,iflags = ldrd_mnem[idx]
437 olist = (
438 ArmRegOper(Rd),
439 ArmImmOffsetOper(Rn, (Rs<<4)+Rm),
440 )
441 else:
442 raise Exception("extra_load_store: invalid instruction: %.8x:\t%.8x"%(va,opval))
443
444 return (opcode, mnem, olist, iflags)
445
446
448 ocode,sflag,Rn,Rd = dpbase(opval)
449 Rm = opval & 0xf
450 shtype = (opval >> 5) & 0x3
451 Rs = (opval >> 8) & 0xf
452
453 if ocode in dp_noRn:
454 olist = (
455 ArmRegOper(Rd),
456 ArmRegShiftRegOper(Rm, shtype, Rs),
457 )
458 elif ocode in dp_noRd:
459 olist = (
460 ArmRegOper(Rn),
461 ArmRegShiftRegOper(Rm, shtype, Rs),
462 )
463 else:
464 olist = (
465 ArmRegOper(Rd),
466 ArmRegOper(Rn),
467 ArmRegShiftRegOper(Rm, shtype, Rs),
468 )
469
470 opcode = (IENC_DP_REG_SHIFT << 16) + ocode
471 if sflag > 0:
472 iflags = IF_PSR_S
473 else:
474 iflags = 0
475 return (opcode, dp_mnem[ocode], olist, iflags)
476
477 multfail = (None, None, None,)
491
493 ocode,sflag,Rn,Rd = dpbase(opval)
494 imm = opval & 0xff
495 rot = (opval >> 7) & 0x1e
496
497
498 if ocode in dp_noRn:
499 olist = (
500 ArmRegOper(Rd),
501 ArmImmOper(imm, rot, S_ROR),
502 )
503 elif ocode in dp_noRd:
504 olist = (
505 ArmRegOper(Rn),
506 ArmImmOper(imm, rot, S_ROR),
507 )
508 else:
509 olist = (
510 ArmRegOper(Rd),
511 ArmRegOper(Rn),
512 ArmImmOper(imm, rot, S_ROR),
513 )
514
515 opcode = (IENC_DP_IMM << 16) + ocode
516 if sflag > 0:
517 iflags = IF_PSR_S
518 else:
519 iflags = 0
520 return (opcode, dp_mnem[ocode], olist, iflags)
521
523 raise Exception("p_undef: invalid instruction (by definition in ARM spec): %.8x:\t%.8x"%(va,opval))
524 opcode = IENC_UNDEF
525 mnem = "undefined instruction"
526 olist = (
527 ArmImmOper(opval),
528 )
529
530 return (opcode, mnem, olist, 0)
531
533 imm = opval & 0xff
534 rot = (opval>>8) & 0xf
535 r = (opval>>22) & 1
536 mask = (opval>>16) & 0xf
537
538 immed = ((imm>>rot) + (imm<<(32-rot))) & 0xffffffff
539
540 olist = (
541 ArmPgmStatRegOper(mask),
542 ArmImmOper(immed),
543 )
544
545 opcode = (IENC_MOV_IMM_STAT << 16)
546 return (opcode, "msr", olist, 0)
547
548 ldr_mnem = ("str", "ldr")
549 tsizes = (4, 1,)
551 pubwl = (opval>>20) & 0x1f
552 Rn = (opval>>16) & 0xf
553 Rd = (opval>>12) & 0xf
554 imm = opval & 0xfff
555
556 if pubwl & 4:
557 iflags = IF_B
558 if (pubwl & 0x12) == 2:
559 iflags |= IF_T
560 else:
561 iflags = 0
562
563 olist = (
564 ArmRegOper(Rd),
565 ArmImmOffsetOper(Rn, imm, va, pubwl=pubwl)
566 )
567
568 opcode = (IENC_LOAD_IMM_OFF << 16)
569 return (opcode, ldr_mnem[pubwl&1], olist, iflags)
570
572 pubwl = (opval>>20) & 0x1f
573 Rd = (opval>>12) & 0xf
574 Rn = (opval>>16) & 0xf
575 Rm = opval & 0xf
576 shtype = (opval>>5) & 0x3
577 shval = (opval>>7) & 0x1f
578
579 if pubwl & 4:
580 iflags = IF_B
581 if (pubwl & 0x12) == 2:
582 iflags |= IF_T
583 else:
584 iflags = 0
585
586 olist = (
587 ArmRegOper(Rd),
588 ArmScaledOffsetOper(Rn, Rm, shtype, shval, va, pubwl),
589 )
590
591 opcode = (IENC_LOAD_REG_OFF << 16)
592 return (opcode, ldr_mnem[pubwl&1], olist, iflags)
593
594
615
616
617 parallel_mnem = []
618 par_suffixes = ("add16", "addsubx", "subaddx", "sub16", "add8", "sub8", "", "")
619 par_prefixes = ("","s","q","sh","","u","uq","uh")
620 for pre in par_prefixes:
621 for suf in par_suffixes:
622 parallel_mnem.append(pre+suf)
623
624 parallel_mnem = tuple(parallel_mnem)
625
642
643
644 xtnd_mnem = []
645 xtnd_suffixes = ("xtab16","xtab","xtah","xtb16","xtb","xth",)
646 xtnd_prefixes = ("s","u")
647 for pre in xtnd_prefixes:
648 for suf in xtnd_suffixes:
649 xtnd_mnem.append(pre+suf)
650
651 xtnd_mnem = tuple(xtnd_mnem)
652
653 pkh_mnem = ('pkhbt', 'pkhtb',)
654 sat_mnem = ('ssat','usat')
655 sat16_mnem = ('ssat16','usat16')
656 rev_mnem = ('rev','rev16',None,'revsh',)
657
752
753
756
757
783
785 raise Exception("p_arch_undef: invalid instruction (by definition in ARM spec): %.8x:\t%.8x"%(va,opval))
786
787 return (IENC_ARCH_UNDEF, 'arch undefined', (ArmImmOper(opval),), 0)
788
789 ldm_mnem = ("stm", "ldm")
790
792 puswl = (opval>>20) & 0x1f
793 mnem = ldm_mnem[(puswl&1)]
794
795 flags = ((puswl&0x18)<<21) + IF_DA
796 Rn = (opval>>16) & 0xf
797 reg_list = opval & 0xffff
798
799 olist = (
800 ArmRegOper(Rn),
801 ArmRegListOper(reg_list, puswl),
802 )
803 if puswl & 2:
804 flags |= IF_W
805 olist[0].oflags |= OF_W
806 if puswl & 4:
807 flags |= IF_UM
808 olist[1].oflags |= OF_UM
809
810
811 opcode = (IENC_LOAD_MULT << 16)
812 return (opcode, mnem, olist, flags)
813
815 return (encoding << 16) + index
816
817 INS_B = instrenc(IENC_BRANCH, 0)
818 INS_BL = instrenc(IENC_BRANCH, 1)
819 INS_BX = instrenc(IENC_MISC, 3)
820 INS_BXJ = instrenc(IENC_MISC, 5)
821 INS_BLX = IENC_UNCOND_BLX
822
823 b_mnem = ("b", "bl",)
825 off = e_bits.signed(opval, 3)
826 off <<= 2
827 link = (opval>>24) & 1
828
829
830
831 olist = ( ArmOffsetOper(off, va),)
832 if link:
833 flags = envi.IF_CALL
834 else:
835 flags = envi.IF_BRANCH
836
837 opcode = (IENC_BRANCH << 16) + link
838 return (opcode, b_mnem[link], olist, flags)
839
840 ldc_mnem = ("stc", "ldc",)
842 punwl = (opval>>20) & 0x1f
843 Rn = (opval>>16) & 0xf
844 CRd = (opval>>12) & 0xf
845 cp_num = (opval>>8) & 0xf
846 offset = opval & 0xff
847
848 if punwl & 4:
849 iflags = IF_L
850 else:
851 iflags = 0
852
853 olist = (
854 ArmCoprocOper(cp_num),
855 ArmCoprocRegOper(CRd),
856 ArmImmOffsetOper(Rn, offset*4, va, pubwl=punwl),
857 )
858
859 opcode = (IENC_COPROC_LOAD << 16)
860 return (opcode, ldc_mnem[punwl&1], olist, iflags)
861
862 mcrr_mnem = ("mcrr", "mrrc")
880
881 cdp_mnem = ["cdp" for x in range(15)]
882 cdp_mnem.append("cdp2")
883
904
905 mcr_mnem = ("mcr", "mrc")
926
928 swint = opval & 0xffffff
929
930 olist = ( ArmImmOper(swint), )
931 opcode = IENC_SWINT << 16 + 1
932 return (opcode, "swi", olist, 0)
933
934 cps_mnem = ("cps","cps FAIL-bad encoding","cpsie","cpsid")
935 mcrr2_mnem = ("mcrr2", "mrrc2")
936 ldc2_mnem = ("stc2", "ldc2",)
937 mcr2_mnem = ("mcr2", "mrc2")
939
940 if opval & 0x0f000000 == 0x0f000000:
941
942 opcode = IENC_SWINT << 16 + 2
943 immval = opval & 0x00ffffff
944 return (opcode, 'swi', (ArmImmOper(immval),), 0)
945
946 optop = ( opval >> 26 ) & 0x3
947 if optop == 0:
948 if opval & 0xfff10020 == 0xf1000000:
949
950 imod = (opval>>18)&3
951 mmod = (opval>>17)&1
952 aif = (opval>>5)&7
953 mode = opval&0x1f
954 mnem = cps_mnem[imod]
955
956 if imod & 2:
957 olist = [
958 ArmCPSFlagsOper(aif)
959 ]
960 else:
961 olist = []
962 if mmod:
963 olist.append(ArmImmOper(mode))
964
965 opcode = IENC_UNCOND_CPS + imod
966 return (opcode, mnem, olist, 0)
967 elif (opval & 0xffff00f0) == 0xf1010000:
968
969 e = (opval>>9) & 1
970 mnem = "setend"
971 olist = ( ArmEndianOper(e), )
972 opcode = IENC_UNCOND_SETEND
973 return (opcode, mnem, olist, 0)
974 else:
975 raise Exception("p_uncond (ontop=0): invalid instruction: %.8x:\t%.8x"%(va,opval))
976 elif optop == 1:
977 if (opval & 0xf570f000) == 0xf550f000:
978
979
980 mnem = "pld"
981 I = (opval>>25) & 1
982 Rn = (opval>>16) & 0xf
983 U = (opval>>23) & 1
984 opcode = IENC_UNCOND_PLD
985 if I:
986 immoffset = opval & 0xfff
987 olist = (ArmImmOffsetOper(Rn, immoffset, va, U<<3),)
988 else:
989 Rm = opval & 0xf
990 shtype = (opval>>5) & 3
991 shval = (opval>>7) & 0x1f
992 olist = (ArmScaledOffsetOper(Rn, Rm, shtype, shval, va, pubwl), )
993 return (opcode, mnem, olist, 0)
994 else:
995 raise Exception("p_uncond (ontop=1): invalid instruction: %.8x:\t%.8x"%(va,opval))
996 elif optop == 2:
997 if (opval & 0xfe5f0f00) == 0xf84d0500:
998
999 pu_w = (opval>>21) & 0xf
1000 mnem = "srs"
1001 flags = ((pu_w<<10) & 0x3000) + IF_DA
1002 mode = opval & 0xf
1003
1004 olist = (
1005 ArmModeOper(mode, pu_w&1),
1006 )
1007 opcode = IENC_UNCOND_SRS
1008 return (opcode, mnem, olist, flags)
1009 elif (opval & 0xfe500f00) == 0xf8100a00:
1010
1011 pu = (opval>>23) & 3
1012 mnem = "rfe"
1013 flags = (pu<<12) + IF_DA
1014 Rn = (opval>>16) & 0xf
1015
1016 olist = (
1017 ArmRegOper(Rn),
1018 )
1019 opcode = IENC_UNCOND_RFE
1020 return (opcode, mnem, olist, flags)
1021
1022 elif (opval & 0xfe000000) == 0xfa000000:
1023
1024 mnem = "blx"
1025 h = (opval>>23) & 2
1026 imm_offset = e_bits.signed(opval, 3) + h
1027
1028 olist = (
1029 ArmOffsetOper(imm_offset, va),
1030 )
1031
1032 opcode = INS_BLX
1033 return (opcode, mnem, olist, 0)
1034 else:
1035 raise Exception("p_uncond (ontop=2): invalid instruction: %.8x:\t%.8x"%(va,opval))
1036 else:
1037 if (opval & 0xffe00000) == 0xfc400000:
1038
1039 Rn = (opval>>16) & 0xf
1040 Rd = (opval>>12) & 0xf
1041 cp_num = (opval>>8) & 0xf
1042 opcode = (opval>>4) & 0xf
1043 CRm = opval & 0xf
1044 mnem = mcrr2_mnem[(opval>>20) & 1]
1045
1046 olist = (
1047 ArmCoprocOper(cp_num),
1048 ArmCoprocOpcodeOper(opcode),
1049 ArmRegOper(Rd),
1050 ArmRegOper(Rn),
1051 ArmCoprocRegOper(CRm),
1052 )
1053 opcode = IENC_COPROC_RREG_XFER<<16
1054 return (opcode, mnem, olist, 0)
1055
1056 elif (opval & 0xfe000000) == 0xfc000000:
1057
1058 punwl = (opval>>20) & 0x1f
1059 Rn = (opval>>16) & 0xf
1060 CRd = (opval>>12) & 0xf
1061 cp_num = (opval>>8) & 0xf
1062 offset = opval & 0xff
1063
1064 if punwl & 4:
1065 iflags = IF_L
1066 else:
1067 iflags = 0
1068
1069 olist = (
1070 ArmCoprocOper(cp_num),
1071 ArmCoprocRegOper(CRd),
1072 ArmImmOffsetOper(Rn, offset*4, va, pubwl=punwl),
1073 )
1074
1075 opcode = (IENC_COPROC_LOAD << 16)
1076 return (opcode, ldc2_mnem[punwl&1], olist, iflags)
1077
1078 elif (opval & 0xff000010) == 0xfe000000:
1079
1080 return p_coproc_dp(opval)
1081 elif (opval & 0xff000010) == 0xfe000010:
1082
1083 opcode1 = (opval>>21) & 0x7
1084 load = (opval>>20) & 1
1085 CRn = (opval>>16) & 0xf
1086 Rd = (opval>>12) & 0xf
1087 cp_num = (opval>>8) & 0xf
1088 opcode2 = (opval>>5) & 0x7
1089 CRm = opval & 0xf
1090
1091 olist = (
1092 ArmCoprocOper(cp_num),
1093 ArmCoprocOpcodeOper(opcode1),
1094 ArmRegOper(Rd),
1095 ArmCoprocRegOper(CRn),
1096 ArmCoprocRegOper(CRm),
1097 ArmCoprocOpcodeOper(opcode2),
1098 )
1099
1100 opcode = (IENC_COPROC_REG_XFER << 16)
1101 return (opcode, mcr2_mnem[load], olist, 0)
1102 else:
1103 raise Exception("p_uncond (ontop=3): invalid instruction: %.8x:\t%.8x"%(va,opval))
1104
1105
1106
1107 ienc_parsers_tmp = [None for x in range(21)]
1108
1109 ienc_parsers_tmp[IENC_DP_IMM_SHIFT] = p_dp_imm_shift
1110 ienc_parsers_tmp[IENC_MISC] = p_misc
1111 ienc_parsers_tmp[IENC_MISC1] = p_misc1
1112 ienc_parsers_tmp[IENC_EXTRA_LOAD] = p_extra_load_store
1113 ienc_parsers_tmp[IENC_DP_REG_SHIFT] = p_dp_reg_shift
1114 ienc_parsers_tmp[IENC_MULT] = p_mult
1115 ienc_parsers_tmp[IENC_UNDEF] = p_undef
1116 ienc_parsers_tmp[IENC_MOV_IMM_STAT] = p_mov_imm_stat
1117 ienc_parsers_tmp[IENC_DP_IMM] = p_dp_imm
1118 ienc_parsers_tmp[IENC_LOAD_IMM_OFF] = p_load_imm_off
1119 ienc_parsers_tmp[IENC_LOAD_REG_OFF] = p_load_reg_off
1120 ienc_parsers_tmp[IENC_ARCH_UNDEF] = p_arch_undef
1121 ienc_parsers_tmp[IENC_MEDIA] = p_media
1122 ienc_parsers_tmp[IENC_LOAD_MULT] = p_load_mult
1123 ienc_parsers_tmp[IENC_BRANCH] = p_branch
1124 ienc_parsers_tmp[IENC_COPROC_RREG_XFER] = p_coproc_dbl_reg_xfer
1125 ienc_parsers_tmp[IENC_COPROC_LOAD] = p_coproc_load
1126 ienc_parsers_tmp[IENC_COPROC_DP] = p_coproc_dp
1127 ienc_parsers_tmp[IENC_COPROC_REG_XFER] = p_coproc_reg_xfer
1128 ienc_parsers_tmp[IENC_SWINT] = p_swint
1129 ienc_parsers_tmp[IENC_UNCOND] = p_uncond
1130
1131 ienc_parsers = tuple(ienc_parsers_tmp)
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148 s_0_table = (
1149
1150 (binary("00000000000000000000000000010000"), binary("00000000000000000000000000000000"), IENC_DP_IMM_SHIFT),
1151 (binary("00000001100100000000000000010000"), binary("00000001000000000000000000000000"), IENC_MISC),
1152 (binary("00000001100100000000000010010000"), binary("00000001000000000000000000010000"), IENC_MISC1),
1153 (binary("00000001000000000000000011110000"), binary("00000000000000000000000010010000"), IENC_MULT),
1154 (binary("00000001001000000000000010010000"), binary("00000001001000000000000010010000"), IENC_EXTRA_LOAD),
1155 (binary("00000000000000000000000010010000"), binary("00000000000000000000000010010000"), IENC_EXTRA_LOAD),
1156 (binary("00000000000000000000000010010000"), binary("00000000000000000000000000010000"), IENC_DP_REG_SHIFT),
1157 (0,0, IENC_UNDEF),
1158 )
1159
1160 s_1_table = (
1161 (binary("00000001100110000000000000000000"), binary("00000001000000000000000000000000"), IENC_UNDEF),
1162 (binary("00000001100110000000000000000000"), binary("00000001001000000000000000000000"), IENC_MOV_IMM_STAT),
1163 (0,0, IENC_DP_IMM),
1164 )
1165
1166 s_3_table = (
1167 (binary("00000001111100000000000011110000"),binary("00000001111100000000000011110000"), IENC_ARCH_UNDEF),
1168 (binary("00000000000000000000000000010000"),binary("00000000000000000000000000010000"), IENC_MEDIA),
1169 (0,0, IENC_LOAD_REG_OFF),
1170 )
1171
1172 s_6_table = (
1173 (binary("00001111111000000000000000000000"),binary("00001100010000000000000000000000"), IENC_COPROC_RREG_XFER),
1174 (binary("00001110000000000000000000000000"),binary("00001100000000000000000000000000"), IENC_COPROC_LOAD),
1175 )
1176
1177 s_7_table = (
1178 (binary("00000001000000000000000000000000"),binary("00000001000000000000000000000000"), IENC_SWINT),
1179 (binary("00000001000000000000000000010000"),binary("00000000000000000000000000010000"), IENC_COPROC_REG_XFER),
1180 (0, 0, IENC_COPROC_DP),
1181 )
1182
1183
1184 inittable = [
1185 (None, s_0_table),
1186 (None, s_1_table),
1187 (IENC_LOAD_IMM_OFF, None),
1188 (None, s_3_table),
1189 (IENC_LOAD_MULT, None),
1190 (IENC_BRANCH, None),
1191 (None, s_6_table),
1192 (None, s_7_table),
1193 (IENC_UNCOND, None),
1194 ]
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 endian_names = ("le","be")
1212
1213
1214
1216
1218 return int(hash(self.mnem) ^ (self.size << 4))
1219
1221 return int(self.size)
1222
1224 """
1225 Return a list of tuples. Each tuple contains the target VA of the
1226 branch, and a possible set of flags showing what type of branch it is.
1227
1228 See the BR_FOO types for all the supported envi branch flags....
1229 Example: for bva,bflags in op.getBranches():
1230 """
1231 ret = []
1232
1233 if not self.iflags & envi.IF_NOFALL:
1234 ret.append((self.va + self.size, envi.BR_FALL))
1235
1236
1237 flags = 0
1238 if self.prefixes != COND_AL:
1239 flags |= envi.BR_COND
1240 if self.opcode == INS_B:
1241 oper = self.opers[0]
1242 ret.append((oper.getOperValue(self), flags))
1243 elif self.opcode == INS_BL:
1244 oper = self.opers[0]
1245 ret.append((oper.getOperValue(self), flags | envi.BR_PROC))
1246 return ret
1247
1249 """
1250 Render this opcode to the specified memory canvas
1251 """
1252 mnem = self.mnem + cond_codes.get(self.prefixes)
1253 mcanv.addNameText(mnem, typename="mnemonic")
1254 mcanv.addText(" ")
1255
1256
1257 imax = len(self.opers)
1258 lasti = imax - 1
1259 for i in xrange(imax):
1260 oper = self.opers[i]
1261 oper.render(mcanv, self, i)
1262 if i != lasti:
1263 mcanv.addText(",")
1264
1265
1267 mnem = self.mnem + cond_codes.get(self.prefixes)
1268
1269
1270
1271
1272 daib_flags = self.iflags & IF_DAIB_MASK
1273 if self.iflags & IF_L:
1274 mnem += 'l'
1275 elif self.iflags & IF_PSR_S:
1276 mnem += 's'
1277 elif daib_flags > 0:
1278 idx = ((daib_flags)>>24)
1279 mnem += daib[idx]
1280 else:
1281 if self.iflags & IF_S:
1282 mnem += 's'
1283 if self.iflags & IF_B:
1284 mnem += 'b'
1285 if self.iflags & IF_H:
1286 mnem += 'h'
1287 elif self.iflags & IF_T:
1288 mnem += 't'
1289
1290 x = []
1291
1292 for o in self.opers:
1293 x.append(o.repr(self))
1294 return mnem + " " + ", ".join(x)
1295
1298 self.reg = reg
1299 self.oflags = oflags
1300
1302 if not isinstance(oper, self.__class__):
1303 return False
1304 if self.reg != oper.reg:
1305 return False
1306 if self.oflags != oper.oflags:
1307 return False
1308 return True
1309
1311 return self.reg == 15
1312
1317
1322
1323 - def render(self, mcanv, op, idx):
1324 rname = arm_regs[self.reg][0]
1325 if self.oflags & OF_W:
1326 rname += "!"
1327 mcanv.addNameText(rname, typename='registers')
1328
1329
1330 - def repr(self, op):
1331 rname = arm_regs[self.reg][0]
1332 if self.oflags & OF_W:
1333 rname += "!"
1334 return rname
1335
1337
1338 - def __init__(self, reg, shtype, shreg):
1339 self.reg = reg
1340 self.shtype = shtype
1341 self.shreg = shreg
1342
1344 if not isinstance(oper, self.__class__):
1345 return False
1346 if self.reg != oper.reg:
1347 return False
1348 if self.shtype != oper.shtype:
1349 return False
1350 if self.shreg != oper.shreg:
1351 return False
1352 return True
1353
1355 return self.reg == 15
1356
1361
1362 - def render(self, mcanv, op, idx):
1369
1370 - def repr(self, op):
1373
1375
1376 - def __init__(self, reg, shtype, shimm):
1377 if shimm == 0:
1378 if shtype == S_ROR:
1379 shtype = S_RRX
1380 elif shtype == S_LSR or shtype == S_ASR:
1381 shimm = 32
1382 self.reg = reg
1383 self.shtype = shtype
1384 self.shimm = shimm
1385
1387 if not isinstance(oper, self.__class__):
1388 return False
1389 if self.reg != oper.reg:
1390 return False
1391 if self.shtype != oper.shtype:
1392 return False
1393 if self.shimm != oper.shimm:
1394 return False
1395 return True
1396
1398 return self.reg == 15
1399
1404
1405 - def render(self, mcanv, op, idx):
1416
1417 - def repr(self, op):
1418 rname = arm_regs[self.reg][0]
1419 retval = [ rname ]
1420 if self.shimm != 0:
1421 retval.append(", "+shift_names[self.shtype])
1422 retval.append("#%d"%self.shimm)
1423 elif self.shtype == S_RRX:
1424 retval.append(shift_names[self.shtype])
1425 return " ".join(retval)
1426
1428
1430 self.val = val
1431 self.shval = shval
1432 self.shtype = shtype
1433
1435 if not isinstance(oper, self.__class__):
1436 return False
1437 if self.getOperValue(None) != oper.getOperValue(None):
1438 return False
1439 return True
1440
1443
1445 return shifters[self.shtype](self.val, self.shval)
1446
1447 - def render(self, mcanv, op, idx):
1448 if self.shval != 0:
1449 mcanv.addNameText('#0x%.2x,%d' % (self.val, self.shval))
1450 else:
1451 mcanv.addNameText('#0x%.2x' % (self.val))
1452
1453 - def repr(self, op):
1454 if self.shval != 0:
1455 return '#0x%.2x,%d' % (self.val, self.shval)
1456 else:
1457 return '#0x%.2x' % (self.val)
1458
1460 - def __init__(self, base_reg, offset_reg, shtype, shval, va, pubwl=0):
1461 if shval == 0:
1462 if shtype == S_ROR:
1463 shtype = S_RRX
1464 elif shtype == S_LSR or shtype == S_ASR:
1465 shval = 32
1466 self.base_reg = base_reg
1467 self.offset_reg = offset_reg
1468 self.shtype = shtype
1469 self.shval = shval
1470 self.pubwl = pubwl
1471
1473 if not isinstance(oper, self.__class__):
1474 return False
1475 if self.base_reg != oper.base_reg:
1476 return False
1477 if self.offset_reg != oper.offset_reg:
1478 return False
1479 if self.shtype != oper.shtype:
1480 return False
1481 if self.shval != oper.shval:
1482 return False
1483 if self.pubwl != oper.pubwl:
1484 return False
1485 return True
1486
1488 return self.base_reg == 15
1489
1491 if emu == None:
1492 return None
1493 raise Exception("FIXME: Implement ArmScaledOffsetOper.getOperValue()")
1494 return None
1495
1496 - def render(self, mcanv, op, idx):
1497 pom = ('-','')[(self.pubwl>>4)&1]
1498 idxing = self.pubwl & 0x12
1499 basereg = arm_regs[self.base_reg][0]
1500 offreg = arm_regs[self.offset_reg][0]
1501 shname = shift_names[self.shtype]
1502
1503 mcanv.addText('[')
1504 mcanv.addNameText(basereg, typename='registers')
1505 if (idxing&0x10) == 0:
1506 mcanv.addText('], ')
1507 else:
1508 mcanv.addText(', ')
1509 mcanv.addText(pom)
1510 mcanv.addNameText(offreg, typename='registers')
1511 mcanv.addText(' ')
1512 if self.shval != 0:
1513 mcanv.addNameText(shname)
1514 mcanv.addText(' ')
1515 mcanv.addNameText('#%d' % self.shval)
1516 if idxing == 0x10:
1517 mcanv.addText(']')
1518 elif idxing != 0:
1519 mcanv.addText(']!')
1520
1521 - def repr(self, op):
1522 pom = ('-','')[(self.pubwl>>4)&1]
1523 idxing = self.pubwl & 0x12
1524 basereg = arm_regs[self.base_reg][0]
1525 offreg = arm_regs[self.offset_reg][0]
1526 shname = shift_names[self.shtype]
1527 if self.shval != 0:
1528 shval = "%s #%d"%(shname,self.shval)
1529 elif self.shtype == S_RRX:
1530 shval = shname
1531 else:
1532 shval = ""
1533 if (idxing&0x10) == 0:
1534 tname = '[%s], %s%s %s' % (basereg, pom, offreg, shval)
1535 elif idxing == 0x10:
1536 tname = '[%s, %s%s %s]' % (basereg, pom, offreg, shval)
1537 else:
1538 tname = '[%s, %s%s %s]!' % (basereg, pom, offreg, shval)
1539 return tname
1540
1542 - def __init__(self, base_reg, offset_reg, va, pubwl=0):
1543 self.base_reg = base_reg
1544 self.offset_reg = offset_reg
1545 self.pubwl = pubwl
1546
1548 if not isinstance(oper, self.__class__):
1549 return False
1550 if self.base_reg != oper.base_reg:
1551 return False
1552 if self.offset_reg != oper.offset_reg:
1553 return False
1554 if self.pubwl != oper.pubwl:
1555 return False
1556 return True
1557
1559 return self.base_reg == 15
1560
1562 if emu == None:
1563 return None
1564 raise Exception("FIXME: Implement ArmRegOffsetOper.getOperValue()")
1565
1566 - def render(self, mcanv, op, idx):
1567 pom = ('-','')[(self.pubwl>>4)&1]
1568 idxing = self.pubwl & 0x12
1569 basereg = arm_regs[self.base_reg][0]
1570 offreg = arm_regs[self.offset_reg][0]
1571
1572 mcanv.addText('[')
1573 mcanv.addNameText(basereg, typename='registers')
1574 if (idxing&0x10) == 0:
1575 mcanv.addText('] ')
1576 else:
1577 mcanv.addText(', ')
1578 mcanv.addText(pom)
1579 mcanv.addNameText(offreg, typename='registers')
1580 if idxing == 0x10:
1581 mcanv.addText(']')
1582 elif idxing != 0:
1583 mcanv.addText(']!')
1584
1585 - def repr(self, op):
1586 pom = ('-','')[(self.pubwl>>4)&1]
1587 idxing = self.pubwl & 0x12
1588 basereg = arm_regs[self.base_reg][0]
1589 offreg = arm_regs[self.offset_reg][0]
1590 if (idxing&0x10) == 0:
1591 tname = '[%s], %s%s' % (basereg, pom, offreg)
1592 elif idxing == 0x10:
1593 tname = '[%s, %s%s]' % (basereg, pom, offreg)
1594 else:
1595 tname = '[%s, %s%s]!' % (basereg, pom, offreg)
1596 return tname
1597
1599 - def __init__(self, base_reg, offset, va, pubwl=8):
1600 self.base_reg = base_reg
1601 self.offset = offset
1602 self.pubwl = pubwl
1603
1605 if not isinstance(oper, self.__class__):
1606 return False
1607 if self.base_reg != oper.base_reg:
1608 return False
1609 if self.offset != oper.offset:
1610 return False
1611 if self.pubwl != oper.pubwl:
1612 return False
1613 return True
1614
1616 return self.base_reg == 15
1617
1619 if emu == None:
1620 return None
1621
1622 pubwl = self.pubwl >> 1
1623 w = pubwl & 1
1624 pubwl >>=1
1625 b = pubwl & 1
1626 pubwl >>=1
1627 u = pubwl & 1
1628 pubwl >>=1
1629 p = pubwl
1630
1631 addr = emu.getRegister(self.basereg)
1632 if u:
1633 addr += self.offset
1634 else:
1635 addr -= self.offset
1636
1637 fmt = ("B", "<L")[b]
1638 ret = emu.readMemoryFormat(addr, fmt)
1639 return ret
1640
1641 - def render(self, mcanv, op, idx):
1642 pom = ('-','')[(self.pubwl>>4)&1]
1643 idxing = self.pubwl & 0x12
1644 basereg = arm_regs[self.base_reg][0]
1645 mcanv.addText('[')
1646 mcanv.addNameText(basereg, typename='registers')
1647 if self.offset == 0:
1648 mcanv.addText(']')
1649 else:
1650 if (idxing&0x10) == 0:
1651 mcanv.addText('] ')
1652 else:
1653 mcanv.addText(', ')
1654
1655 mcanv.addNameText('#%s0x%x' % (pom,self.offset))
1656
1657 if idxing == 0x10:
1658 mcanv.addText(']')
1659 elif idxing != 0:
1660 mcanv.addText(']!')
1661
1662 - def repr(self, op):
1663 pom = ('-','')[(self.pubwl>>4)&1]
1664 idxing = (self.pubwl) & 0x12
1665 basereg = arm_regs[self.base_reg][0]
1666 if self.offset != 0:
1667 offset = ", #%s0x%x"%(pom,self.offset)
1668 else:
1669 offset = ""
1670
1671 if (idxing&0x10) == 0:
1672 tname = '[%s]%s' % (basereg, offset)
1673 else:
1674 if idxing == 0x10:
1675 tname = '[%s%s]' % (basereg,offset)
1676 else:
1677 tname = '[%s%s]!' % (basereg,offset)
1678 return tname
1679
1682 self.val = val
1683 self.va = va
1684
1686 if not isinstance(oper, self.__class__):
1687 return False
1688 if self.val != oper.val:
1689 return False
1690 if self.va != oper.va:
1691 return False
1692 return True
1693
1696
1698 return self.va + self.val + op.size + 4
1699
1700 - def render(self, mcanv, op, idx):
1707
1708 - def repr(self, op):
1709 targ = self.getOperValue(op)
1710 tname = "#0x%.8x" % targ
1711 return tname
1712
1713 psrs = ("CPSR", "SPSR")
1717
1719 if not isinstance(oper, self.__class__):
1720 return False
1721 if self.val != oper.val:
1722 return False
1723 return True
1724
1727
1729 if emu == None:
1730 return None
1731 raise Exception("FIXME: Implement ArmPgmStatRegOper.getOperValue()")
1732 return None
1733
1734 - def repr(self, op):
1735 return psrs[self.val]
1736
1738
1741
1743 if not isinstance(oper, self.__class__):
1744 return False
1745 if self.val != oper.val:
1746 return False
1747 return True
1748
1751
1753 if emu == None:
1754 return None
1755 raise Exception("FIXME: Implement ArmPgmStatRegOper.getOperValue()")
1756 return None
1757
1758 - def repr(self, op):
1759 s = ["PSR_",psr_fields[self.val]]
1760 return "".join(s)
1761
1763 - def repr(self, op):
1765
1768
1771
1774 self.val = val
1775 self.oflags = oflags
1776
1778 if not isinstance(oper, self.__class__):
1779 return False
1780 if self.val != oper.val:
1781 return False
1782 if self.oflags != oper.oflags:
1783 return False
1784 return True
1785
1787 return self.val & 0x80 == 0x80
1788
1789 - def render(self, mcanv, op, idx):
1798
1800 if emu == None:
1801 return None
1802 reglist = []
1803 for regidx in xrange(16):
1804
1805 if self.val & (1<<regidx):
1806 reg = emu.getRegister(regidx)
1807 reglist.append(reg)
1808 return reglist
1809
1810 - def repr(self, op):
1811 s = [ "{" ]
1812 for l in xrange(16):
1813 if (self.val & (1<<l)):
1814 s.append(arm_regs[l][0])
1815 s.append('}')
1816 if self.oflags & OF_UM:
1817 s.append('^')
1818 return " ".join(s)
1819
1820 aif_flags = (None, 'f','i','if','a','af','ai','aif')
1824
1826 if not isinstance(oper, self.__class__):
1827 return False
1828 if self.flags != oper.flags:
1829 return False
1830 return True
1831
1834
1836 if emu == None:
1837 return None
1838 raise Exception("FIXME: Implement ArmPSRFlagsOper.getOperValue() (does it want to be a bitmask? or the actual value according to the PSR?)")
1839 return None
1840
1841 - def repr(self, op):
1843
1847
1849 if not isinstance(oper, self.__class__):
1850 return False
1851 if self.val != oper.val:
1852 return False
1853 return True
1854
1857
1860
1861 - def repr(self, op):
1862 return "%d"%self.val
1863
1867
1869 if not isinstance(oper, self.__class__):
1870 return False
1871 if self.val != oper.val:
1872 return False
1873 return True
1874
1877
1880
1881 - def repr(self, op):
1882 return "p%d"%self.val
1883
1885 - def __init__(self, val, shtype=None, shval=None):
1886 self.val = val
1887 self.shval = shval
1888 self.shtype = shtype
1889
1891 if not isinstance(oper, self.__class__):
1892 return False
1893 if self.val != oper.val:
1894 return False
1895 if self.shval != oper.shval:
1896 return False
1897 if self.shtype != oper.shtype:
1898 return False
1899 return True
1900
1903
1905 if emu == None:
1906 return None
1907 raise Exception("FIXME: Implement ArmCoprocRegOper.getOperValue()")
1908 return None
1909
1910 - def repr(self, op):
1911 return "c%d"%self.val
1912
1913
1914
1916
1917 - def disasm(self, bytes, offset, va, trackMode=False):
1918 """
1919 Parse a sequence of bytes out into an envi.Opcode instance.
1920 """
1921 opbytes = bytes[offset:offset+4]
1922 opval, = struct.unpack("<L", opbytes)
1923
1924 cond = opval >> 28
1925
1926
1927 encfam = (opval >> 25) & 0x7
1928 if cond == COND_EXTENDED:
1929 enc = IENC_UNCOND
1930
1931 else:
1932
1933 enc,nexttab = inittable[encfam]
1934 if nexttab != None:
1935 for mask,val,penc in nexttab:
1936 if (opval & mask) == val:
1937 enc = penc
1938 break
1939
1940
1941 if enc == None:
1942 raise InvalidInstruction(bytes[:4])
1943
1944 opcode, mnem, olist, flags = ienc_parsers[enc](opval, va)
1945
1946
1947 if cond == COND_AL:
1948 if opcode in (INS_B, INS_BX):
1949 flags |= envi.IF_NOFALL
1950
1951 elif ( len(olist) and
1952 isinstance(olist[0], ArmRegOper) and
1953 olist[0].involvesPC() ):
1954
1955 showop = True
1956 flags |= envi.IF_NOFALL
1957
1958
1959
1960 op = ArmOpcode(va, opcode, mnem, cond, 4, olist, flags)
1961 op.encoder = enc
1962
1963 return op
1964
1966
1967
1968
1969
1970 olist = op.opers
1971 if op.opcode == INS_BX:
1972 self.parent.setMode( olist[0]&1 )
1973 self.parent.setMode( 1 )
1974 elif ( len(olist) > 1 and
1975 isinstance(olist[0], ArmRegOper) and
1976 olist[0].reg == REG_PC ):
1977 mode = olist[1].getOperValue(op)
1978 if mode != None:
1979 self.parent.setMode( mode&1 )
1980
1981
1982
1983 elif op.opcode == INS_BXJ:
1984 if self.parent.jzl_enabled:
1985 self.parent.setMode( 2 )
1986 else:
1987 pass
1988
1989