Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
sem.py
Go to the documentation of this file.
2 from miasm2.ir.ir import ir, irbloc
3 from miasm2.arch.arm.arch import mn_arm, mn_armt
4 from miasm2.arch.arm.regs import *
5 
6 
7 # liris.cnrs.fr/~mmrissa/lib/exe/fetch.php?media=armv7-a-r-manual.pdf
8 
9 EXCEPT_PRIV_INSN = (1 << 17)
10 
11 # CPSR: N Z C V
12 
13 
15  return [ExprAff(zf, ExprCond(a, ExprInt1(0), ExprInt1(1)))]
16 
17 
19  return [ExprAff(nf, a.msb())]
20 
21 
23  e = []
24  e += update_flag_zf(a)
25  e += update_flag_nf(a)
26  return e
27 
28 
30  e = []
31  e += update_flag_zn(a)
32  # XXX TODO: set cf if ROT imm in argument
33  #e.append(ExprAff(cf, ExprInt1(0)))
34  return e
35 
36 
38  e = []
39  e += update_flag_zn(a)
40  return e
41 
42 
43 def check_ops_msb(a, b, c):
44  if not a or not b or not c or a != b or a != c:
45  raise ValueError('bad ops size %s %s %s' % (a, b, c))
46 
47 
48 def arith_flag(a, b, c):
49  a_s, b_s, c_s = a.size, b.size, c.size
50  check_ops_msb(a_s, b_s, c_s)
51  a_s, b_s, c_s = a.msb(), b.msb(), c.msb()
52  return a_s, b_s, c_s
53 
54 # checked: ok for adc add because b & c before +cf
55 
56 def update_flag_add_cf(op1, op2, res):
57  "Compute cf in @res = @op1 + @op2"
58  return ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb())
59 
60 
61 def update_flag_add_of(op1, op2, res):
62  "Compute of in @res = @op1 + @op2"
63  return ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb())
64 
65 
66 # checked: ok for sbb add because b & c before +cf
67 def update_flag_sub_cf(op1, op2, res):
68  "Compote CF in @res = @op1 - @op2"
69  return ExprAff(cf,
70  ((((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()) ^ ExprInt1(1))
71 
72 
73 def update_flag_sub_of(op1, op2, res):
74  "Compote OF in @res = @op1 - @op2"
75  return ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb())
76 
77 # z = x+y (+cf?)
78 
79 
80 def update_flag_add(x, y, z):
81  e = []
82  e.append(update_flag_add_cf(x, y, z))
83  e.append(update_flag_add_of(x, y, z))
84  return e
85 
86 # z = x-y (+cf?)
87 
88 
89 def update_flag_sub(x, y, z):
90  e = []
91  e.append(update_flag_sub_cf(x, y, z))
92  e.append(update_flag_sub_of(x, y, z))
93  return e
94 
95 
96 def get_dst(a):
97  if a == PC:
98  return PC
99  return None
100 
101 # instruction definition ##############
102 
103 
104 def adc(ir, instr, a, b, c=None):
105  e = []
106  if c is None:
107  b, c = a, b
108  r = b + c + cf.zeroExtend(32)
109  if instr.name == 'ADCS' and a != PC:
110  e += update_flag_arith(r)
111  e += update_flag_add(b, c, r)
112  e.append(ExprAff(a, r))
113  dst = get_dst(a)
114  if dst is not None:
115  e.append(ExprAff(ir.IRDst, r))
116  return e
117 
118 
119 def add(ir, instr, a, b, c=None):
120  e = []
121  if c is None:
122  b, c = a, b
123  r = b + c
124  if instr.name == 'ADDS' and a != PC:
125  e += update_flag_arith(r)
126  e += update_flag_add(b, c, r)
127  e.append(ExprAff(a, r))
128  dst = get_dst(a)
129  if dst is not None:
130  e.append(ExprAff(ir.IRDst, r))
131  return e
132 
133 
134 def l_and(ir, instr, a, b, c=None):
135  e = []
136  if c is None:
137  b, c = a, b
138  r = b & c
139  if instr.name == 'ANDS' and a != PC:
140  e += update_flag_logic(r)
141  e.append(ExprAff(a, r))
142  dst = get_dst(a)
143  if dst is not None:
144  e.append(ExprAff(ir.IRDst, r))
145  return e
146 
147 
148 def sub(ir, instr, a, b, c=None):
149  e = []
150  if c is None:
151  b, c = a, b
152  r = b - c
153  e.append(ExprAff(a, r))
154  dst = get_dst(a)
155  if dst is not None:
156  e.append(ExprAff(ir.IRDst, r))
157  return e
158 
159 
160 def subs(ir, instr, a, b, c=None):
161  e = []
162  if c is None:
163  b, c = a, b
164  r = b - c
165  e += update_flag_arith(r)
166  e += update_flag_sub(b, c, r)
167  e.append(ExprAff(a, r))
168  dst = get_dst(a)
169  if dst is not None:
170  e.append(ExprAff(ir.IRDst, r))
171  return e
172 
173 
174 def eor(ir, instr, a, b, c=None):
175  e = []
176  if c is None:
177  b, c = a, b
178  r = b ^ c
179  e.append(ExprAff(a, r))
180  dst = get_dst(a)
181  if dst is not None:
182  e.append(ExprAff(ir.IRDst, r))
183  return e
184 
185 
186 def eors(ir, instr, a, b, c=None):
187  e = []
188  if c is None:
189  b, c = a, b
190  r = b ^ c
191  e += update_flag_logic(r)
192  e.append(ExprAff(a, r))
193  dst = get_dst(a)
194  if dst is not None:
195  e.append(ExprAff(ir.IRDst, r))
196  return e
197 
198 
199 def rsb(ir, instr, a, b, c=None):
200  e = []
201  if c is None:
202  b, c = a, b
203  r = c - b
204  e.append(ExprAff(a, r))
205  dst = get_dst(a)
206  if dst is not None:
207  e.append(ExprAff(ir.IRDst, r))
208  return e
209 
210 
211 def rsbs(ir, instr, a, b, c=None):
212  e = []
213  if c is None:
214  b, c = a, b
215  r = c - b
216  e += update_flag_arith(r)
217  e += update_flag_sub(c, b, r)
218  e.append(ExprAff(a, r))
219  dst = get_dst(a)
220  if dst is not None:
221  e.append(ExprAff(ir.IRDst, r))
222  return e
223 
224 
225 def sbc(ir, instr, a, b, c=None):
226  e = []
227  if c is None:
228  b, c = a, b
229  r = (b + cf.zeroExtend(32)) - (c + ExprInt32(1))
230  e.append(ExprAff(a, r))
231  dst = get_dst(a)
232  if dst is not None:
233  e.append(ExprAff(ir.IRDst, r))
234  return e
235 
236 
237 def sbcs(ir, instr, a, b, c=None):
238  e = []
239  if c is None:
240  b, c = a, b
241  r = (b + cf.zeroExtend(32)) - (c + ExprInt32(1))
242  e += update_flag_arith(r)
243  e += update_flag_sub(b, c, r)
244  e.append(ExprAff(a, r))
245  dst = get_dst(a)
246  if dst is not None:
247  e.append(ExprAff(ir.IRDst, r))
248  return e
249 
250 
251 def rsc(ir, instr, a, b, c=None):
252  e = []
253  if c is None:
254  b, c = a, b
255  r = (c + cf.zeroExtend(32)) - (b + ExprInt32(1))
256  e.append(ExprAff(a, r))
257  dst = get_dst(a)
258  if dst is not None:
259  e.append(ExprAff(ir.IRDst, r))
260  return e
261 
262 
263 def rscs(ir, instr, a, b, c=None):
264  e = []
265  if c is None:
266  b, c = a, b
267  r = (c + cf.zeroExtend(32)) - (b + ExprInt32(1))
268  e.append(ExprAff(a, r))
269  e += update_flag_arith(r)
270  e += update_flag_sub(c, b, r)
271  e.append(ExprAff(a, r))
272  dst = get_dst(a)
273  if dst is not None:
274  e.append(ExprAff(ir.IRDst, r))
275  return e
276 
277 
278 def tst(ir, instr, a, b, c=None):
279  e = []
280  if c is None:
281  b, c = a, b
282  r = b & c
283  e += update_flag_logic(r)
284  return e
285 
286 
287 def teq(ir, instr, a, b, c=None):
288  e = []
289  if c is None:
290  b, c = a, b
291  r = b ^ c
292  e += update_flag_logic(r)
293  return e
294 
295 
296 def l_cmp(ir, instr, a, b, c=None):
297  e = []
298  if c is None:
299  b, c = a, b
300  r = b - c
301  e += update_flag_arith(r)
302  e += update_flag_sub(b, c, r)
303  return e
304 
305 
306 def cmn(ir, instr, a, b, c=None):
307  e = []
308  if c is None:
309  b, c = a, b
310  r = b + c
311  e += update_flag_arith(r)
312  e += update_flag_add(b, c, r)
313  return e
314 
315 
316 def orr(ir, instr, a, b, c=None):
317  e = []
318  if c is None:
319  b, c = a, b
320  r = b | c
321  e.append(ExprAff(a, r))
322  dst = get_dst(a)
323  if dst is not None:
324  e.append(ExprAff(ir.IRDst, r))
325  return e
326 
327 
328 def orrs(ir, instr, a, b, c=None):
329  e = []
330  if c is None:
331  b, c = a, b
332  r = b | c
333  e += update_flag_logic(r)
334  e.append(ExprAff(a, r))
335  dst = get_dst(a)
336  if dst is not None:
337  e.append(ExprAff(ir.IRDst, r))
338  return e
339 
340 
341 def mov(ir, instr, a, b):
342  e = [ExprAff(a, b)]
343  dst = get_dst(a)
344  if dst is not None:
345  e.append(ExprAff(ir.IRDst, b))
346  return e
347 
348 
349 def movt(ir, instr, a, b):
350  r = a | b << ExprInt32(16)
351  e = [ExprAff(a, r)]
352  dst = get_dst(a)
353  if dst is not None:
354  e.append(ExprAff(ir.IRDst, r))
355  return e
356 
357 
358 def movs(ir, instr, a, b):
359  e = []
360  e.append(ExprAff(a, b))
361  # XXX TODO check
362  e += update_flag_logic(b)
363  dst = get_dst(a)
364  if dst is not None:
365  e.append(ExprAff(ir.IRDst, b))
366  return e
367 
368 
369 def mvn(ir, instr, a, b):
370  r = b ^ ExprInt32(-1)
371  e = [ExprAff(a, r)]
372  dst = get_dst(a)
373  if dst is not None:
374  e.append(ExprAff(ir.IRDst, r))
375  return e
376 
377 
378 def mvns(ir, instr, a, b):
379  e = []
380  r = b ^ ExprInt32(-1)
381  e.append(ExprAff(a, r))
382  # XXX TODO check
383  e += update_flag_logic(r)
384  dst = get_dst(a)
385  if dst is not None:
386  e.append(ExprAff(ir.IRDst, r))
387  return e
388 
389 
390 def neg(ir, instr, a, b):
391  e = []
392  r = - b
393  e.append(ExprAff(a, r))
394  dst = get_dst(a)
395  if dst is not None:
396  e.append(ExprAff(ir.IRDst, r))
397  return e
398 
399 def negs(ir, instr, a, b):
400  e = subs(ir, instr, a, ExprInt_from(b, 0), b)
401  return e
402 
403 def bic(ir, instr, a, b, c=None):
404  e = []
405  if c is None:
406  b, c = a, b
407  r = b & (c ^ ExprInt(uint32(-1)))
408  e.append(ExprAff(a, r))
409  dst = get_dst(a)
410  if dst is not None:
411  e.append(ExprAff(ir.IRDst, r))
412  return e
413 
414 
415 def bics(ir, instr, a, b, c=None):
416  e = []
417  if c is None:
418  b, c = a, b
419  r = b & (c ^ ExprInt(uint32(-1)))
420  e += update_flag_logic(r)
421  e.append(ExprAff(a, r))
422  dst = get_dst(a)
423  if dst is not None:
424  e.append(ExprAff(ir.IRDst, r))
425  return e
426 
427 
428 def mla(ir, instr, a, b, c, d):
429  e = []
430  r = (b * c) + d
431  e.append(ExprAff(a, r))
432  dst = get_dst(a)
433  if dst is not None:
434  e.append(ExprAff(ir.IRDst, r))
435  return e
436 
437 
438 def mlas(ir, instr, a, b, c, d):
439  e = []
440  r = (b * c) + d
441  e += update_flag_zn(r)
442  e.append(ExprAff(a, r))
443  dst = get_dst(a)
444  if dst is not None:
445  e.append(ExprAff(ir.IRDst, r))
446  return e
447 
448 
449 def mul(ir, instr, a, b, c = None):
450  e = []
451  if c is None:
452  b, c = a, b
453  r = b * c
454  e.append(ExprAff(a, r))
455  dst = get_dst(a)
456  if dst is not None:
457  e.append(ExprAff(ir.IRDst, r))
458  return e
459 
460 
461 def muls(ir, instr, a, b, c = None):
462  e = []
463  if c is None:
464  b, c = a, b
465  r = b * c
466  e += update_flag_zn(r)
467  e.append(ExprAff(a, r))
468  dst = get_dst(a)
469  if dst is not None:
470  e.append(ExprAff(ir.IRDst, r))
471  return e
472 
473 def umull(ir, instr, a, b, c, d):
474  e = []
475  r = c.zeroExtend(64) * d.zeroExtend(64)
476  e.append(ExprAff(a, r[0:32]))
477  e.append(ExprAff(b, r[32:64]))
478  # r15/IRDst not allowed as output
479  return e
480 
481 def umlal(ir, instr, a, b, c, d):
482  e = []
483  r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)])
484  e.append(ExprAff(a, r[0:32]))
485  e.append(ExprAff(b, r[32:64]))
486  # r15/IRDst not allowed as output
487  return e
488 
489 def smull(ir, instr, a, b, c, d):
490  e = []
491  r = c.signExtend(64) * d.signExtend(64)
492  e.append(ExprAff(a, r[0:32]))
493  e.append(ExprAff(b, r[32:64]))
494  # r15/IRDst not allowed as output
495  return e
496 
497 def smlal(ir, instr, a, b, c, d):
498  e = []
499  r = c.signExtend(64) * d.signExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)])
500  e.append(ExprAff(a, r[0:32]))
501  e.append(ExprAff(b, r[32:64]))
502  # r15/IRDst not allowed as output
503  return e
504 
505 def b(ir, instr, a):
506  e = []
507  e.append(ExprAff(PC, a))
508  e.append(ExprAff(ir.IRDst, a))
509  return e
510 
511 
512 def bl(ir, instr, a):
513  e = []
514  l = ExprInt32(instr.offset + instr.l)
515  e.append(ExprAff(PC, a))
516  e.append(ExprAff(ir.IRDst, a))
517  e.append(ExprAff(LR, l))
518  return e
519 
520 
521 def bx(ir, instr, a):
522  e = []
523  e.append(ExprAff(PC, a))
524  e.append(ExprAff(ir.IRDst, a))
525  return e
526 
527 
528 def blx(ir, instr, a):
529  e = []
530  l = ExprInt32(instr.offset + instr.l)
531  e.append(ExprAff(PC, a))
532  e.append(ExprAff(ir.IRDst, a))
533  e.append(ExprAff(LR, l))
534  return e
535 
536 
537 def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False):
538  e = []
539  wb = False
540  b = b.copy()
541  postinc = False
542  b = b.arg
543  if isinstance(b, ExprOp):
544  if b.op == "wback":
545  wb = True
546  b = b.args[0]
547  if b.op == "postinc":
548  postinc = True
549  if isinstance(b, ExprOp) and b.op in ["postinc", 'preinc']:
550  # XXX TODO CHECK
551  base, off = b.args[0], b.args[1] # ExprInt32(size/8)
552  else:
553  base, off = b, ExprInt32(0)
554  # print a, wb, base, off, postinc
555  if postinc:
556  ad = base
557  else:
558  ad = base + off
559 
560  dmem = False
561  if size in [8, 16]:
562  if store:
563  a = a[:size]
564  m = ExprMem(ad, size=size)
565  elif s_ext:
566  m = ExprMem(ad, size=size).signExtend(a.size)
567  elif z_ext:
568  m = ExprMem(ad, size=size).zeroExtend(a.size)
569  else:
570  raise ValueError('unhandled case')
571  elif size == 32:
572  m = ExprMem(ad, size=size)
573  pass
574  elif size == 64:
575  m = ExprMem(ad, size=32)
576  dmem = True
577  a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1]
578  size = 32
579  else:
580  raise ValueError('the size DOES matter')
581  dst = None
582 
583  if store:
584  e.append(ExprAff(m, a))
585  if dmem:
586  e.append(ExprAff(ExprMem(ad + ExprInt32(4), size=size), a2))
587  else:
588  if a == PC:
589  dst = PC
590  e.append(ExprAff(ir.IRDst, m))
591  e.append(ExprAff(a, m))
592  if dmem:
593  e.append(ExprAff(a2, ExprMem(ad + ExprInt32(4), size=size)))
594 
595  # XXX TODO check multiple write cause by wb
596  if wb or postinc:
597  e.append(ExprAff(base, base + off))
598  return e
599 
600 
601 def ldr(ir, instr, a, b):
602  return st_ld_r(ir, instr, a, b, store=False)
603 
604 
605 def ldrd(ir, instr, a, b):
606  e = st_ld_r(ir, instr, a, b, store=False, size=64)
607  return e
608 
609 
610 def l_str(ir, instr, a, b):
611  return st_ld_r(ir, instr, a, b, store=True)
612 
613 
614 def l_strd(ir, instr, a, b):
615  e = st_ld_r(ir, instr, a, b, store=True, size=64)
616  return e
617 
618 
619 def ldrb(ir, instr, a, b):
620  e = st_ld_r(ir, instr, a, b, store=False, size=8, z_ext=True)
621  return e
622 
623 def ldrsb(ir, instr, a, b):
624  e = st_ld_r(
625  ir, instr, a, b, store=False, size=8, s_ext=True, z_ext=False)
626  return e
627 
628 def strb(ir, instr, a, b):
629  e = st_ld_r(ir, instr, a, b, store=True, size=8)
630  return e
631 
632 
633 def ldrh(ir, instr, a, b):
634  e = st_ld_r(ir, instr, a, b, store=False, size=16, z_ext=True)
635  return e
636 
637 
638 def strh(ir, instr, a, b):
639  e = st_ld_r(ir, instr, a, b, store=True, size=16, z_ext=True)
640  return e
641 
642 
643 def ldrsh(ir, instr, a, b):
644  e = st_ld_r(
645  ir, instr, a, b, store=False, size=16, s_ext=True, z_ext=False)
646  return e
647 
648 
649 def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False):
650  e = []
651  wb = False
652  # sb = False
653  dst = None
654  if isinstance(a, ExprOp) and a.op == 'wback':
655  wb = True
656  a = a.args[0]
657  if isinstance(b, ExprOp) and b.op == 'sbit':
658  # sb = True
659  b = b.args[0]
660  regs = b.args
661  base = a
662  if updown:
663  step = 4
664  else:
665  step = -4
666  regs = regs[::-1]
667  if postinc:
668  pass
669  else:
670  base += ExprInt32(step)
671  for i, r in enumerate(regs):
672  ad = base + ExprInt32(i * step)
673  if store:
674  e.append(ExprAff(ExprMem(ad), r))
675  else:
676  e.append(ExprAff(r, ExprMem(ad)))
677  if r == PC:
678  e.append(ExprAff(ir.IRDst, ExprMem(ad)))
679  # XXX TODO check multiple write cause by wb
680  if wb:
681  if postinc:
682  e.append(ExprAff(a, base + ExprInt32(len(regs) * step)))
683  else:
684  e.append(ExprAff(a, base + ExprInt32((len(regs) - 1) * step)))
685  if store:
686  pass
687  else:
688  assert(isinstance(b, ExprOp) and b.op == "reglist")
689 
690  return e
691 
692 
693 def ldmia(ir, instr, a, b):
694  return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=True)
695 
696 
697 def ldmib(ir, instr, a, b):
698  return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=True)
699 
700 
701 def ldmda(ir, instr, a, b):
702  return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=False)
703 
704 
705 def ldmdb(ir, instr, a, b):
706  return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False)
707 
708 
709 def stmia(ir, instr, a, b):
710  return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=True)
711 
712 
713 def stmib(ir, instr, a, b):
714  return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=True)
715 
716 
717 def stmda(ir, instr, a, b):
718  return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=False)
719 
720 
721 def stmdb(ir, instr, a, b):
722  return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=False)
723 
724 
725 def svc(ir, instr, a):
726  # XXX TODO implement
727  e = [
728  ExprAff(exception_flags, ExprInt32(EXCEPT_PRIV_INSN))]
729  return e
730 
731 
732 def und(ir, instr, a, b):
733  # XXX TODO implement
734  e = []
735  return e
736 
737 # TODO XXX implement correct CF for shifters
738 def lsr(ir, instr, a, b, c = None):
739  e = []
740  if c is None:
741  b, c = a, b
742  r = b >> c
743  e.append(ExprAff(a, r))
744  dst = get_dst(a)
745  if dst is not None:
746  e.append(ExprAff(ir.IRDst, r))
747  return e
748 
749 
750 def lsrs(ir, instr, a, b, c = None):
751  e = []
752  if c is None:
753  b, c = a, b
754  r = b >> c
755  e.append(ExprAff(a, r))
756  e += update_flag_logic(r)
757  dst = get_dst(a)
758  if dst is not None:
759  e.append(ExprAff(ir.IRDst, r))
760  return e
761 
762 def asr(ir, instr, a, b, c=None):
763  e = []
764  if c is None:
765  b, c = a, b
766  r = ExprOp("a>>", b, c)
767  e.append(ExprAff(a, r))
768  dst = get_dst(a)
769  if dst is not None:
770  e.append(ExprAff(ir.IRDst, r))
771  return e
772 
773 def asrs(ir, instr, a, b, c):
774  e = []
775  if c is None:
776  b, c = a, b
777  r = ExprOp("a>>", b, c)
778  e.append(ExprAff(a, r))
779  e += update_flag_logic(r)
780  dst = get_dst(a)
781  if dst is not None:
782  e.append(ExprAff(ir.IRDst, r))
783  return e
784 
785 def lsl(ir, instr, a, b, c = None):
786  e = []
787  if c is None:
788  b, c = a, b
789  r = b << c
790  e.append(ExprAff(a, r))
791  dst = get_dst(a)
792  if dst is not None:
793  e.append(ExprAff(ir.IRDst, r))
794  return e
795 
796 
797 def lsls(ir, instr, a, b, c = None):
798  e = []
799  if c is None:
800  b, c = a, b
801  r = b << c
802  e.append(ExprAff(a, r))
803  e += update_flag_logic(r)
804  dst = get_dst(a)
805  if dst is not None:
806  e.append(ExprAff(ir.IRDst, r))
807  return e
808 
809 
810 def push(ir, instr, a):
811  e = []
812  regs = list(a.args)
813  for i in xrange(len(regs)):
814  r = SP + ExprInt32(-4 * (i + 1))
815  e.append(ExprAff(ExprMem(r), regs[i]))
816  r = SP + ExprInt32(-4 * len(regs))
817  e.append(ExprAff(SP, r))
818  return e
819 
820 
821 def pop(ir, instr, a):
822  e = []
823  regs = list(a.args)
824  dst = None
825  for i in xrange(len(regs)):
826  r = SP + ExprInt32(4 * i)
827  e.append(ExprAff(regs[i], ExprMem(r)))
828  if regs[i] == ir.pc:
829  dst = ExprMem(r)
830  r = SP + ExprInt32(4 * len(regs))
831  e.append(ExprAff(SP, r))
832  if dst is not None:
833  e.append(ExprAff(ir.IRDst, dst))
834  return e
835 
836 
837 def cbz(ir, instr, a, b):
838  e = []
839  lbl_next = ExprId(ir.get_next_label(instr), 32)
840  e.append(ExprAff(ir.IRDst, ExprCond(a, lbl_next, b)))
841  return e
842 
843 
844 def cbnz(ir, instr, a, b):
845  e = []
846  lbl_next = ExprId(ir.get_next_label(instr), 32)
847  e.append(ir.IRDst, ExprCond(a, b, lbl_next))
848  return e
849 
850 
851 
852 def uxtb(ir, instr, a, b):
853  e = []
854  r = b[:8].zeroExtend(32)
855  e.append(ExprAff(a, r))
856  dst = None
857  if PC in a.get_r():
858  dst = PC
859  e.append(ExprAff(ir.IRDst, r))
860  return e
861 
862 def uxth(ir, instr, a, b):
863  e = []
864  r = b[:16].zeroExtend(32)
865  e.append(ExprAff(a, r))
866  dst = None
867  if PC in a.get_r():
868  dst = PC
869  e.append(ExprAff(ir.IRDst, r))
870  return e
871 
872 def sxtb(ir, instr, a, b):
873  e = []
874  r = b[:8].signExtend(32)
875  e.append(ExprAff(a, r))
876  dst = None
877  if PC in a.get_r():
878  dst = PC
879  e.append(ExprAff(ir.IRDst, r))
880  return e
881 
882 def sxth(ir, instr, a, b):
883  e = []
884  r = b[:16].signExtend(32)
885  e.append(ExprAff(a, r))
886  dst = None
887  if PC in a.get_r():
888  dst = PC
889  e.append(ExprAff(ir.IRDst, r))
890  return e
891 
892 
893 def ubfx(ir, instr, a, b, c, d):
894  e = []
895  c = int(c.arg)
896  d = int(d.arg)
897  r = b[c:c+d].zeroExtend(32)
898  e.append(ExprAff(a, r))
899  dst = None
900  if PC in a.get_r():
901  dst = PC
902  e.append(ExprAff(ir.IRDst, r))
903  return e
904 
905 def bfc(ir, instr, a, b, c):
906  e = []
907  start = int(b.arg)
908  stop = start + int(c.arg)
909  out = []
910  last = 0
911  if start:
912  out.append((a[:start], 0, start))
913  last = start
914  if stop - start:
915  out.append((ExprInt32(0)[last:stop], last, stop))
916  last = stop
917  if last < 32:
918  out.append((a[last:], last, 32))
919  r = ExprCompose(out)
920  e.append(ExprAff(a, r))
921  dst = None
922  if PC in a.get_r():
923  dst = PC
924  e.append(ExprAff(ir.IRDst, r))
925  return e
926 
927 def rev(ir, instr, a, b):
928  e = []
929  c = ExprCompose([(b[:8], 24, 32),
930  (b[8:16], 16, 24),
931  (b[16:24], 8, 16),
932  (b[24:32], 0, 8)])
933  e.append(ExprAff(a, c))
934  return e
935 
936 
937 
938 COND_EQ = 0
939 COND_NE = 1
940 COND_CS = 2
941 COND_CC = 3
942 COND_MI = 4
943 COND_PL = 5
944 COND_VS = 6
945 COND_VC = 7
946 COND_HI = 8
947 COND_LS = 9
948 COND_GE = 10
949 COND_LT = 11
950 COND_GT = 12
951 COND_LE = 13
952 COND_AL = 14
953 COND_NV = 15
954 
955 cond_dct = {
956  COND_EQ: "EQ",
957  COND_NE: "NE",
958  COND_CS: "CS",
959  COND_CC: "CC",
960  COND_MI: "MI",
961  COND_PL: "PL",
962  COND_VS: "VS",
963  COND_VC: "VC",
964  COND_HI: "HI",
965  COND_LS: "LS",
966  COND_GE: "GE",
967  COND_LT: "LT",
968  COND_GT: "GT",
969  COND_LE: "LE",
970  COND_AL: "AL",
971  # COND_NV: "NV",
972 }
973 
974 
975 tab_cond = {COND_EQ: zf,
976  COND_NE: ExprCond(zf, ExprInt1(0), ExprInt1(1)),
977  COND_CS: cf,
978  COND_CC: ExprCond(cf, ExprInt1(0), ExprInt1(1)),
979  COND_MI: nf,
980  COND_PL: ExprCond(nf, ExprInt1(0), ExprInt1(1)),
981  COND_VS: of,
982  COND_VC: ExprCond(of, ExprInt1(0), ExprInt1(1)),
983  COND_HI: cf & ExprCond(zf, ExprInt1(0), ExprInt1(1)),
984  # COND_HI: cf,
985  # COND_HI: ExprOp('==',
986  # ExprOp('|', cf, zf),
987  # ExprInt1(0)),
988  COND_LS: ExprCond(cf, ExprInt1(0), ExprInt1(1)) | zf,
989  COND_GE: ExprCond(nf - of, ExprInt1(0), ExprInt1(1)),
990  COND_LT: nf ^ of,
991  # COND_GT: ExprOp('|',
992  # ExprOp('==', zf, ExprInt1(0)) & (nf | of),
993  # ExprOp('==', nf, ExprInt1(0)) & ExprOp('==', of, ExprInt1(0))),
994  COND_GT: (ExprCond(zf, ExprInt1(0), ExprInt1(1)) &
995  ExprCond(nf - of, ExprInt1(0), ExprInt1(1))),
996  COND_LE: zf | (nf ^ of),
997  }
998 
999 
1000 def is_pc_written(ir, instr_ir):
1001  all_pc = ir.mn.pc.values()
1002  for ir in instr_ir:
1003  if ir.dst in all_pc:
1004  return True, ir.dst
1005  return False, None
1006 
1007 
1008 def add_condition_expr(ir, instr, cond, instr_ir):
1009  if cond == COND_AL:
1010  return instr_ir, []
1011  if not cond in tab_cond:
1012  raise ValueError('unknown condition %r' % cond)
1013  cond = tab_cond[cond]
1014 
1015  lbl_next = ExprId(ir.get_next_label(instr), 32)
1016  lbl_do = ExprId(ir.gen_label(), 32)
1017 
1018  dst_cond = ExprCond(cond, lbl_do, lbl_next)
1019  assert(isinstance(instr_ir, list))
1020 
1021  has_irdst = False
1022  for e in instr_ir:
1023  if e.dst == ir.IRDst:
1024  has_irdst = True
1025  break
1026  if not has_irdst:
1027  instr_ir.append(ExprAff(ir.IRDst, lbl_next))
1028  e_do = irbloc(lbl_do.name, [instr_ir])
1029  e = [ExprAff(ir.IRDst, dst_cond)]
1030  return e, [e_do]
1031 
1032 mnemo_func = {}
1033 mnemo_func_cond = {}
1034 mnemo_condm0 = {'add': add,
1035  'sub': sub,
1036  'eor': eor,
1037  'and': l_and,
1038  'rsb': rsb,
1039  'adc': adc,
1040  'sbc': sbc,
1041  'rsc': rsc,
1042 
1043  'tst': tst,
1044  'teq': teq,
1045  'cmp': l_cmp,
1046  'cmn': cmn,
1047  'orr': orr,
1048  'mov': mov,
1049  'movt': movt,
1050  'bic': bic,
1051  'mvn': mvn,
1052  'neg': neg,
1053 
1054  'mul': mul,
1055  'umull': umull,
1056  'umlal': umlal,
1057  'smull': smull,
1058  'smlal': smlal,
1059  'mla': mla,
1060  'ldr': ldr,
1061  'ldrd': ldrd,
1062  'str': l_str,
1063  'strd': l_strd,
1064  'b': b,
1065  'bl': bl,
1066  'svc': svc,
1067  'und': und,
1068  'bx': bx,
1069  'ldrh': ldrh,
1070  'strh': strh,
1071  'ldrsh': ldrsh,
1072  'ldsh': ldrsh,
1073  'uxtb': uxtb,
1074  'uxth': uxth,
1075  'sxtb': sxtb,
1076  'sxth': sxth,
1077  'ubfx': ubfx,
1078  'bfc': bfc,
1079  'rev': rev,
1080  }
1081 
1082 mnemo_condm1 = {'adds': add,
1083  'subs': subs,
1084  'eors': eors,
1085  'ands': l_and,
1086  'rsbs': rsbs,
1087  'adcs': adc,
1088  'sbcs': sbcs,
1089  'rscs': rscs,
1090 
1091  'orrs': orrs,
1092  'movs': movs,
1093  'bics': bics,
1094  'mvns': mvns,
1095  'negs': negs,
1096 
1097  'muls': muls,
1098  'mlas': mlas,
1099  'blx': blx,
1100 
1101  'ldrb': ldrb,
1102  'ldrsb': ldrsb,
1103  'ldsb': ldrsb,
1104  'strb': strb,
1105  }
1106 
1107 mnemo_condm2 = {'ldmia': ldmia,
1108  'ldmib': ldmib,
1109  'ldmda': ldmda,
1110  'ldmdb': ldmdb,
1111 
1112  'ldmfa': ldmda,
1113  'ldmfd': ldmia,
1114  'ldmea': ldmdb,
1115  'ldmed': ldmib, # XXX
1116 
1117 
1118  'stmia': stmia,
1119  'stmib': stmib,
1120  'stmda': stmda,
1121  'stmdb': stmdb,
1122 
1123  'stmfa': stmib,
1124  'stmed': stmda,
1125  'stmfd': stmdb,
1126  'stmea': stmia,
1127  }
1128 
1129 
1130 mnemo_nocond = {'lsr': lsr,
1131  'lsrs': lsrs,
1132  'lsl': lsl,
1133  'lsls': lsls,
1134  'push': push,
1135  'pop': pop,
1136  'asr': asr,
1137  'asrs': asrs,
1138  'cbz': cbz,
1139  'cbnz': cbnz,
1140  }
1141 mn_cond_x = [mnemo_condm0,
1142  mnemo_condm1,
1143  mnemo_condm2]
1144 
1145 for index, mn_base in enumerate(mn_cond_x):
1146  for mn, mf in mn_base.items():
1147  for cond, cn in cond_dct.items():
1148  if cond == COND_AL:
1149  cn = ""
1150  cn = cn.lower()
1151  if index == 0:
1152  mn_mod = mn + cn
1153  else:
1154  mn_mod = mn[:-index] + cn + mn[-index:]
1155  # print mn_mod
1156  mnemo_func_cond[mn_mod] = cond, mf
1157 
1158 for name, mf in mnemo_nocond.items():
1159  mnemo_func_cond[name] = COND_AL, mf
1160 
1161 
1162 def split_expr_dst(ir, instr_ir):
1163  out = []
1164  dst = None
1165  for i in instr_ir:
1166  if i.dst == ir.pc:
1167  out.append(i)
1168  dst = ir.pc # i.src
1169  else:
1170  out.append(i)
1171  return out, dst
1172 
1173 
1174 def get_mnemo_expr(ir, instr, *args):
1175  if not instr.name.lower() in mnemo_func_cond:
1176  raise ValueError('unknown mnemo %s' % instr)
1177  cond, mf = mnemo_func_cond[instr.name.lower()]
1178  instr_ir = mf(ir, instr, *args)
1179  instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir)
1180  return instr, extra_ir
1181 
1182 get_arm_instr_expr = get_mnemo_expr
1183 
1184 
1185 class arminfo:
1186  mode = "arm"
1187  # offset
1188 
1189 
1190 class ir_arml(ir):
1191  def __init__(self, symbol_pool=None):
1192  ir.__init__(self, mn_arm, "l", symbol_pool)
1193  self.pc = PC
1194  self.sp = SP
1195  self.IRDst = ExprId('IRDst', 32)
1196 
1197  def get_ir(self, instr):
1198  args = instr.args
1199  # ir = get_mnemo_expr(self, self.name.lower(), *args)
1200  if len(args) and isinstance(args[-1], ExprOp):
1201  if args[-1].op == 'rrx':
1202  args[-1] = ExprCompose(
1203  [(args[-1].args[0][1:], 0, 31), (cf, 31, 32)])
1204  elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and
1205  isinstance(args[-1].args[-1], ExprId)):
1206  args[-1] = ExprOp(args[-1].op,
1207  args[-1].args[0],
1208  args[-1].args[-1][:8].zeroExtend(32))
1209  instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
1210  # if self.name.startswith('B'):
1211  # return instr_ir, extra_ir
1212  for i, x in enumerate(instr_ir):
1213  x = ExprAff(x.dst, x.src.replace_expr(
1214  {self.pc: ExprInt32(instr.offset + 8)}))
1215  instr_ir[i] = x
1216  for b in extra_ir:
1217  for irs in b.irs:
1218  for i, x in enumerate(irs):
1219  x = ExprAff(x.dst, x.src.replace_expr(
1220  {self.pc: ExprInt32(instr.offset + 8)}))
1221  irs[i] = x
1222  # return out_ir, extra_ir
1223  return instr_ir, extra_ir
1224 
1225 
1227  def __init__(self, symbol_pool=None):
1228  ir.__init__(self, mn_arm, "b", symbol_pool)
1229  self.pc = PC
1230  self.sp = SP
1231  self.IRDst = ExprId('IRDst', 32)
1232 
1233 class ir_armtl(ir):
1234  def __init__(self, symbol_pool=None):
1235  ir.__init__(self, mn_armt, "l", symbol_pool)
1236  self.pc = PC
1237  self.sp = SP
1238  self.IRDst = ExprId('IRDst', 32)
1239 
1240  def get_ir(self, instr):
1241  return get_mnemo_expr(self, instr, *instr.args)
1242 
1244  def __init__(self, symbol_pool=None):
1245  ir.__init__(self, mn_armt, "b", symbol_pool)
1246  self.pc = PC
1247  self.sp = SP
1248  self.IRDst = ExprId('IRDst', 32)
1249 
def update_flag_add_cf
Definition: sem.py:56
def update_flag_sub_cf
Definition: sem.py:67
def update_flag_add
Definition: sem.py:80
def update_flag_sub_of
Definition: sem.py:73
def update_flag_logic
Definition: sem.py:29
def update_flag_arith
Definition: sem.py:37
def update_flag_zf
Definition: sem.py:14
def add_condition_expr
Definition: sem.py:1008
def update_flag_add_of
Definition: sem.py:61
def check_ops_msb
Definition: sem.py:43
def update_flag_sub
Definition: sem.py:89
def arith_flag
Definition: sem.py:48
def update_flag_zn
Definition: sem.py:22
def get_mnemo_expr
Definition: sem.py:1174
def split_expr_dst
Definition: sem.py:1162
def update_flag_nf
Definition: sem.py:18