Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
sem.py
Go to the documentation of this file.
1 from miasm2.expression import expression as m2_expr
2 from miasm2.ir.ir import ir, irbloc
3 from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs
4 from miasm2.arch.aarch64.regs import *
5 from miasm2.core.sembuilder import SemBuilder
6 
7 EXCEPT_PRIV_INSN = (1 << 17)
8 
9 # CPSR: N Z C V
10 
11 
13  return [m2_expr.ExprAff(zf, m2_expr.ExprCond(a, m2_expr.ExprInt1(0), m2_expr.ExprInt1(1)))]
14 
15 
17  return [m2_expr.ExprAff(nf, a.msb())]
18 
19 
21  e = []
22  e += update_flag_zf(a)
23  e += update_flag_nf(a)
24  return e
25 
26 
28  e = []
29  e += update_flag_zn(a)
30  # XXX TODO: set cf if ROT imm in argument
31  # e.append(m2_expr.ExprAff(cf, m2_expr.ExprInt1(0)))
32  return e
33 
34 
36  e = []
37  e += update_flag_zn(a)
38  return e
39 
40 
41 def check_ops_msb(a, b, c):
42  if not a or not b or not c or a != b or a != c:
43  raise ValueError('bad ops size %s %s %s' % (a, b, c))
44 
45 
46 def arith_flag(a, b, c):
47  a_s, b_s, c_s = a.size, b.size, c.size
48  check_ops_msb(a_s, b_s, c_s)
49  a_s, b_s, c_s = a.msb(), b.msb(), c.msb()
50  return a_s, b_s, c_s
51 
52 # checked: ok for adc add because b & c before +cf
53 
54 
55 def update_flag_add_cf(op1, op2, res):
56  "Compute cf in @res = @op1 + @op2"
57  return m2_expr.ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb())
58 
59 
60 def update_flag_add_of(op1, op2, res):
61  "Compute of in @res = @op1 + @op2"
62  return m2_expr.ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb())
63 
64 
65 # checked: ok for sbb add because b & c before +cf
66 def update_flag_sub_cf(op1, op2, res):
67  "Compote CF in @res = @op1 - @op2"
68  return m2_expr.ExprAff(cf,
69  ((((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()) ^ m2_expr.ExprInt1(1))
70 
71 
72 def update_flag_sub_of(op1, op2, res):
73  "Compote OF in @res = @op1 - @op2"
74  return m2_expr.ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb())
75 
76 # z = x+y (+cf?)
77 
78 
79 def update_flag_add(x, y, z):
80  e = []
81  e.append(update_flag_add_cf(x, y, z))
82  e.append(update_flag_add_of(x, y, z))
83  return e
84 
85 # z = x-y (+cf?)
86 
87 
88 def update_flag_sub(x, y, z):
89  e = []
90  e.append(update_flag_sub_cf(x, y, z))
91  e.append(update_flag_sub_of(x, y, z))
92  return e
93 
94 
95 cond2expr = {'EQ': zf,
96  'NE': zf ^ m2_expr.ExprInt1(1),
97  'CS': cf,
98  'CC': cf ^ m2_expr.ExprInt1(1),
99  'MI': nf,
100  'PL': nf ^ m2_expr.ExprInt1(1),
101  'VS': of,
102  'VC': of ^ m2_expr.ExprInt1(1),
103  'HI': cf & (zf ^ m2_expr.ExprInt1(1)),
104  'LS': (cf ^ m2_expr.ExprInt1(1)) | zf,
105  'GE': nf ^ of ^ m2_expr.ExprInt1(1),
106  'LT': nf ^ of,
107  'GT': ((zf ^ m2_expr.ExprInt1(1)) &
108  (nf ^ of ^ m2_expr.ExprInt1(1))),
109  'LE': zf | (nf ^ of),
110  'AL': m2_expr.ExprInt1(1),
111  'NV': m2_expr.ExprInt1(0)
112  }
113 
114 
115 def extend_arg(dst, arg):
116  if not isinstance(arg, m2_expr.ExprOp):
117  return arg
118 
119  op, (reg, shift) = arg.op, arg.args
120  if op == 'SXTW':
121  base = reg.signExtend(dst.size)
122  else:
123  base = reg.zeroExtend(dst.size)
124 
125  out = base << (shift.zeroExtend(dst.size)
126  & m2_expr.ExprInt_from(dst, dst.size - 1))
127  return out
128 
129 
130 # SemBuilder context
131 ctx = {"PC": PC,
132  "LR": LR,
133  "nf": nf,
134  "zf": zf,
135  "cf": cf,
136  "of": of,
137  "cond2expr": cond2expr,
138  "extend_arg": extend_arg,
139  "m2_expr":m2_expr
140  }
141 
142 sbuild = SemBuilder(ctx)
143 
144 
145 # instruction definition ##############
146 
147 @sbuild.parse
148 def add(arg1, arg2, arg3):
149  arg1 = arg2 + extend_arg(arg2, arg3)
150 
151 
152 @sbuild.parse
153 def sub(arg1, arg2, arg3):
154  arg1 = arg2 - extend_arg(arg2, arg3)
155 
156 
157 @sbuild.parse
158 def neg(arg1, arg2):
159  arg1 = - arg2
160 
161 
162 @sbuild.parse
163 def and_l(arg1, arg2, arg3):
164  arg1 = arg2 & extend_arg(arg2, arg3)
165 
166 
167 @sbuild.parse
168 def eor(arg1, arg2, arg3):
169  arg1 = arg2 ^ extend_arg(arg2, arg3)
170 
171 
172 @sbuild.parse
173 def eon(arg1, arg2, arg3):
174  arg1 = arg2 ^ (~extend_arg(arg2, arg3))
175 
176 
177 @sbuild.parse
178 def orr(arg1, arg2, arg3):
179  arg1 = arg2 | extend_arg(arg2, arg3)
180 
181 
182 @sbuild.parse
183 def orn(arg1, arg2, arg3):
184  arg1 = arg2 | (~extend_arg(arg2, arg3))
185 
186 
187 @sbuild.parse
188 def bic(arg1, arg2, arg3):
189  arg1 = arg2 & (~extend_arg(arg2, arg3))
190 
191 
192 @sbuild.parse
193 def mvn(arg1, arg2):
194  arg1 = (~extend_arg(arg1, arg2))
195 
196 
197 def adds(ir, instr, arg1, arg2, arg3):
198  e = []
199  arg3 = extend_arg(arg2, arg3)
200  res = arg2 + arg3
201  e += update_flag_arith(res)
202  e += update_flag_add(arg2, arg3, res)
203  e.append(m2_expr.ExprAff(arg1, res))
204  return e, []
205 
206 
207 def subs(ir, instr, arg1, arg2, arg3):
208  e = []
209  arg3 = extend_arg(arg2, arg3)
210  res = arg2 - arg3
211  e += update_flag_arith(res)
212  e += update_flag_sub(arg2, arg3, res)
213  e.append(m2_expr.ExprAff(arg1, res))
214  return e, []
215 
216 
217 def cmp(ir, instr, arg1, arg2):
218  e = []
219  arg2 = extend_arg(arg1, arg2)
220  res = arg1 - arg2
221  e += update_flag_arith(res)
222  e += update_flag_sub(arg1, arg2, res)
223  return e, []
224 
225 
226 def cmn(ir, instr, arg1, arg2):
227  e = []
228  arg2 = extend_arg(arg1, arg2)
229  res = arg1 + arg2
230  e += update_flag_arith(res)
231  e += update_flag_add(arg1, arg2, res)
232  return e, []
233 
234 
235 def ands(ir, instr, arg1, arg2, arg3):
236  e = []
237  arg3 = extend_arg(arg2, arg3)
238  res = arg2 & arg3
239  e += update_flag_logic(res)
240  e.append(m2_expr.ExprAff(arg1, res))
241  return e, []
242 
243 def tst(ir, instr, arg1, arg2):
244  e = []
245  arg2 = extend_arg(arg1, arg2)
246  res = arg1 & arg2
247  e += update_flag_logic(res)
248  return e, []
249 
250 
251 @sbuild.parse
252 def lsl(arg1, arg2, arg3):
253  arg1 = arg2 << (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1))
254 
255 
256 @sbuild.parse
257 def lsr(arg1, arg2, arg3):
258  arg1 = arg2 >> (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1))
259 
260 
261 @sbuild.parse
262 def asr(arg1, arg2, arg3):
263  arg1 = m2_expr.ExprOp(
264  'a>>', arg2, (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1)))
265 
266 
267 @sbuild.parse
268 def mov(arg1, arg2):
269  arg1 = arg2
270 
271 
272 def movk(ir, instr, arg1, arg2):
273  e = []
274  if isinstance(arg2, m2_expr.ExprOp):
275  assert(arg2.op == 'slice_at' and
276  isinstance(arg2.args[0], m2_expr.ExprInt) and
277  isinstance(arg2.args[1], m2_expr.ExprInt))
278  value, shift = int(arg2.args[0].arg), int(arg2.args[1].arg)
279  e.append(
280  m2_expr.ExprAff(arg1[shift:shift + 16], m2_expr.ExprInt16(value)))
281  else:
282  e.append(m2_expr.ExprAff(arg1[:16], m2_expr.ExprInt16(int(arg2.arg))))
283 
284  return e, []
285 
286 
287 @sbuild.parse
288 def movz(arg1, arg2):
289  arg1 = arg2
290 
291 
292 @sbuild.parse
293 def movn(arg1, arg2):
294  arg1 = ~arg2
295 
296 
297 @sbuild.parse
298 def bl(arg1):
299  PC = arg1
300  ir.IRDst = arg1
301  LR = m2_expr.ExprInt64(instr.offset + instr.l)
302 
303 @sbuild.parse
304 def csel(arg1, arg2, arg3, arg4):
305  cond_expr = cond2expr[arg4.name]
306  arg1 = arg2 if cond_expr else arg3
307 
308 
309 def csinc(ir, instr, arg1, arg2, arg3, arg4):
310  e = []
311  cond_expr = cond2expr[arg4.name]
312  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
313  arg2,
314  arg3 + m2_expr.ExprInt_from(arg3, 1))))
315  return e, []
316 
317 
318 def csinv(ir, instr, arg1, arg2, arg3, arg4):
319  e = []
320  cond_expr = cond2expr[arg4.name]
321  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
322  arg2,
323  ~arg3)))
324  return e, []
325 
326 
327 def csneg(ir, instr, arg1, arg2, arg3, arg4):
328  e = []
329  cond_expr = cond2expr[arg4.name]
330  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
331  arg2,
332  -arg3)))
333  return e, []
334 
335 
336 def cset(ir, instr, arg1, arg2):
337  e = []
338  cond_expr = cond2expr[arg2.name]
339  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
340  m2_expr.ExprInt_from(
341  arg1, 1),
342  m2_expr.ExprInt_from(arg1, 0))))
343  return e, []
344 
345 
346 def csetm(ir, instr, arg1, arg2):
347  e = []
348  cond_expr = cond2expr[arg2.name]
349  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
350  m2_expr.ExprInt_from(
351  arg1, -1),
352  m2_expr.ExprInt_from(arg1, 0))))
353  return e, []
354 
355 
356 def get_mem_access(mem):
357  updt = None
358  if isinstance(mem, m2_expr.ExprOp):
359  if mem.op == 'preinc':
360  addr = mem.args[0] + mem.args[1]
361  elif mem.op == 'segm':
362  base = mem.args[0]
363  op, (reg, shift) = mem.args[1].op, mem.args[1].args
364  if op == 'SXTW':
365  off = reg.signExtend(base.size) << shift.zeroExtend(base.size)
366  addr = base + off
367  elif op == 'UXTW':
368  off = reg.zeroExtend(base.size) << shift.zeroExtend(base.size)
369  addr = base + off
370  elif op == 'LSL':
371  if isinstance(shift, m2_expr.ExprInt) and int(shift.arg) == 0:
372  addr = base + reg.zeroExtend(base.size)
373  else:
374  addr = base + \
375  (reg.zeroExtend(base.size)
376  << shift.zeroExtend(base.size))
377  else:
378  raise NotImplementedError('bad op')
379  elif mem.op == "postinc":
380  addr, off = mem.args
381  updt = m2_expr.ExprAff(addr, addr + off)
382  elif mem.op == "preinc_wb":
383  base, off = mem.args
384  addr = base + off
385  updt = m2_expr.ExprAff(base, base + off)
386  else:
387  raise NotImplementedError('bad op')
388  else:
389  raise NotImplementedError('bad op')
390  return addr, updt
391 
392 
393 
394 def ldr(ir, instr, arg1, arg2):
395  e = []
396  addr, updt = get_mem_access(arg2)
397  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size)))
398  if updt:
399  e.append(updt)
400  return e, []
401 
402 
403 def ldrb(ir, instr, arg1, arg2):
404  e = []
405  addr, updt = get_mem_access(arg2)
406  e.append(
407  m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 8).zeroExtend(arg1.size)))
408  if updt:
409  e.append(updt)
410  return e, []
411 
412 
413 def ldrh(ir, instr, arg1, arg2):
414  e = []
415  addr, updt = get_mem_access(arg2)
416  e.append(
417  m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 16).zeroExtend(arg1.size)))
418  if updt:
419  e.append(updt)
420  return e, []
421 
422 
423 def l_str(ir, instr, arg1, arg2):
424  e = []
425  addr, updt = get_mem_access(arg2)
426  e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1))
427  if updt:
428  e.append(updt)
429  return e, []
430 
431 
432 def strb(ir, instr, arg1, arg2):
433  e = []
434  addr, updt = get_mem_access(arg2)
435  e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 8), arg1[:8]))
436  if updt:
437  e.append(updt)
438  return e, []
439 
440 
441 def strh(ir, instr, arg1, arg2):
442  e = []
443  addr, updt = get_mem_access(arg2)
444  e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 16), arg1[:16]))
445  if updt:
446  e.append(updt)
447  return e, []
448 
449 
450 def stp(ir, instr, arg1, arg2, arg3):
451  e = []
452  addr, updt = get_mem_access(arg3)
453  e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1))
454  e.append(
455  m2_expr.ExprAff(m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, arg1.size / 8), arg2.size), arg2))
456  if updt:
457  e.append(updt)
458  return e, []
459 
460 
461 def ldp(ir, instr, arg1, arg2, arg3):
462  e = []
463  addr, updt = get_mem_access(arg3)
464  e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size)))
465  e.append(
466  m2_expr.ExprAff(arg2, m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, arg1.size / 8), arg2.size)))
467  if updt:
468  e.append(updt)
469  return e, []
470 
471 
472 def ldrsw(ir, instr, arg1, arg2):
473  e = []
474  addr, updt = get_mem_access(arg2)
475  e.append(
476  m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 32).signExtend(arg1.size)))
477  if updt:
478  e.append(updt)
479  return e, []
480 
481 
482 def sbfm(ir, instr, arg1, arg2, arg3, arg4):
483  e = []
484  rim, sim = int(arg3.arg), int(arg4.arg) + 1
485  if sim > rim:
486  res = arg2[rim:sim].signExtend(arg1.size)
487  else:
488  shift = m2_expr.ExprInt_from(arg2, arg2.size - rim)
489  res = (arg2[:sim].signExtend(arg1.size) << shift)
490  e.append(m2_expr.ExprAff(arg1, res))
491  return e, []
492 
493 
494 def ubfm(ir, instr, arg1, arg2, arg3, arg4):
495  e = []
496  rim, sim = int(arg3.arg), int(arg4.arg) + 1
497  if sim > rim:
498  res = arg2[rim:sim].zeroExtend(arg1.size)
499  else:
500  shift = m2_expr.ExprInt_from(arg2, arg2.size - rim)
501  res = (arg2[:sim].zeroExtend(arg1.size) << shift)
502  e.append(m2_expr.ExprAff(arg1, res))
503  return e, []
504 
505 def bfm(ir, instr, arg1, arg2, arg3, arg4):
506  e = []
507  rim, sim = int(arg3.arg), int(arg4.arg) + 1
508  if sim > rim:
509  res = arg2[rim:sim]
510  e.append(m2_expr.ExprAff(arg1[:sim-rim], res))
511  else:
512  shift_i = arg2.size - rim
513  shift = m2_expr.ExprInt_from(arg2, shift_i)
514  res = arg2[:sim]
515  e.append(m2_expr.ExprAff(arg1[shift_i:shift_i+sim], res))
516  return e, []
517 
518 
519 @sbuild.parse
520 def madd(arg1, arg2, arg3, arg4):
521  arg1 = arg2 * arg3 + arg4
522 
523 
524 @sbuild.parse
525 def msub(arg1, arg2, arg3, arg4):
526  arg1 = arg4 - (arg2 * arg3)
527 
528 
529 @sbuild.parse
530 def udiv(arg1, arg2, arg3):
531  arg1 = m2_expr.ExprOp('udiv', arg2, arg3)
532 
533 
534 @sbuild.parse
535 def cbz(arg1, arg2):
536  dst = m2_expr.ExprId(ir.get_next_label(instr), 64) if arg1 else arg2
537  PC = dst
538  ir.IRDst = dst
539 
540 
541 @sbuild.parse
542 def cbnz(arg1, arg2):
543  dst = arg2 if arg1 else m2_expr.ExprId(ir.get_next_label(instr), 64)
544  PC = dst
545  ir.IRDst = dst
546 
547 
548 @sbuild.parse
549 def tbz(arg1, arg2, arg3):
550  bitmask = m2_expr.ExprInt_from(arg1, 1) << arg2
551  dst = m2_expr.ExprId(
552  ir.get_next_label(instr), 64) if arg1 & bitmask else arg3
553  PC = dst
554  ir.IRDst = dst
555 
556 
557 @sbuild.parse
558 def tbnz(arg1, arg2, arg3):
559  bitmask = m2_expr.ExprInt_from(arg1, 1) << arg2
560  dst = arg3 if arg1 & bitmask else m2_expr.ExprId(
561  ir.get_next_label(instr), 64)
562  PC = dst
563  ir.IRDst = dst
564 
565 
566 @sbuild.parse
567 def b_ne(arg1):
568  dst = m2_expr.ExprId(ir.get_next_label(instr), 64) if zf else arg1
569  PC = dst
570  ir.IRDst = dst
571 
572 
573 @sbuild.parse
574 def b_eq(arg1):
575  dst = arg1 if zf else m2_expr.ExprId(ir.get_next_label(instr), 64)
576  PC = dst
577  ir.IRDst = dst
578 
579 
580 @sbuild.parse
581 def b_ge(arg1):
582  cond = cond2expr['GE']
583  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
584  PC = dst
585  ir.IRDst = dst
586 
587 
588 @sbuild.parse
589 def b_gt(arg1):
590  cond = cond2expr['GT']
591  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
592  PC = dst
593  ir.IRDst = dst
594 
595 
596 @sbuild.parse
597 def b_cc(arg1):
598  cond = cond2expr['CC']
599  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
600  PC = dst
601  ir.IRDst = dst
602 
603 
604 @sbuild.parse
605 def b_cs(arg1):
606  cond = cond2expr['CS']
607  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
608  PC = dst
609  ir.IRDst = dst
610 
611 
612 @sbuild.parse
613 def b_hi(arg1):
614  cond = cond2expr['HI']
615  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
616  PC = dst
617  ir.IRDst = dst
618 
619 
620 @sbuild.parse
621 def b_le(arg1):
622  cond = cond2expr['LE']
623  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
624  PC = dst
625  ir.IRDst = dst
626 
627 
628 @sbuild.parse
629 def b_ls(arg1):
630  cond = cond2expr['LS']
631  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
632  PC = dst
633  ir.IRDst = dst
634 
635 
636 @sbuild.parse
637 def b_lt(arg1):
638  cond = cond2expr['LT']
639  dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
640  PC = dst
641  ir.IRDst = dst
642 
643 
644 @sbuild.parse
645 def ret(arg1):
646  PC = arg1
647  ir.IRDst = arg1
648 
649 
650 @sbuild.parse
651 def adrp(arg1, arg2):
652  arg1 = (PC & m2_expr.ExprInt64(0xfffffffffffff000)) + arg2
653 
654 
655 @sbuild.parse
656 def b(arg1):
657  PC = arg1
658  ir.IRDst = arg1
659 
660 
661 @sbuild.parse
662 def br(arg1):
663  PC = arg1
664  ir.IRDst = arg1
665 
666 
667 @sbuild.parse
668 def nop():
669  """Do nothing"""
670 
671 
672 
673 @sbuild.parse
674 def extr(arg1, arg2, arg3, arg4):
675  compose = m2_expr.ExprCompose([(arg2, 0, arg2.size),
676  (arg3, arg2.size, arg2.size+arg3.size)])
677  arg1 = compose[int(arg4.arg):int(arg4.arg)+arg1.size]
678 
679 mnemo_func = sbuild.functions
680 mnemo_func.update({
681  'and': and_l,
682  'adds': adds,
683  'ands': ands,
684  'tst': tst,
685  'subs': subs,
686  'cmp': cmp,
687  'cmn': cmn,
688  'movk': movk,
689  'csinc': csinc,
690  'csinv': csinv,
691  'csneg': csneg,
692  'cset': cset,
693  'csetm': csetm,
694 
695  'b.ne': b_ne,
696  'b.eq': b_eq,
697  'b.ge': b_ge,
698  'b.gt': b_gt,
699  'b.cc': b_cc,
700  'b.cs': b_cs,
701  'b.hi': b_hi,
702  'b.le': b_le,
703  'b.ls': b_ls,
704  'b.lt': b_lt,
705 
706  'ret': ret,
707  'stp': stp,
708  'ldp': ldp,
709 
710  'ldr': ldr,
711  'ldrb': ldrb,
712  'ldrh': ldrh,
713 
714  'ldur': ldr,
715  'ldurb': ldrb,
716  'ldurh': ldrh,
717 
718  'str': l_str,
719  'strb': strb,
720  'strh': strh,
721 
722  'stur': l_str,
723  'sturb': strb,
724  'sturh': strh,
725 
726  'ldrsw': ldrsw,
727 
728 
729  'bfm': bfm,
730  'sbfm': sbfm,
731  'ubfm': ubfm,
732 
733  'extr': extr,
734 
735 })
736 
737 
738 def get_mnemo_expr(ir, instr, *args):
739  if not instr.name.lower() in mnemo_func:
740  raise NotImplementedError('unknown mnemo %s' % instr)
741  instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
742  return instr, extra_ir
743 
744 
746  mode = "aarch64"
747  # offset
748 
749 
751 
752  def __init__(self, symbol_pool=None):
753  ir.__init__(self, mn_aarch64, "l", symbol_pool)
754  self.pc = PC
755  self.sp = SP
756  self.IRDst = m2_expr.ExprId('IRDst', 64)
757 
758  def get_ir(self, instr):
759  args = instr.args
760  if len(args) and isinstance(args[-1], m2_expr.ExprOp):
761  if (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and
762  isinstance(args[-1].args[-1], m2_expr.ExprId)):
763  args[-1] = m2_expr.ExprOp(args[-1].op,
764  args[-1].args[0],
765  args[-1].args[-1][:8].zeroExtend(32))
766  instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
767  self.mod_pc(instr, instr_ir, extra_ir)
768  instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir)
769 
770  return instr_ir, extra_ir
771 
773  return e.replace_expr(replace_regs)
774 
776  dst = self.expr_fix_regs_for_mode(e.dst)
777  src = self.expr_fix_regs_for_mode(e.src)
778  return m2_expr.ExprAff(dst, src)
779 
780  def irbloc_fix_regs_for_mode(self, irbloc, mode=64):
781  for irs in irbloc.irs:
782  for i, e in enumerate(irs):
783  """
784  special case for 64 bits:
785  if destination is a 32 bit reg, zero extend the 64 bit reg
786  """
787  if (isinstance(e.dst, m2_expr.ExprId) and
788  e.dst.size == 32 and
789  e.dst in replace_regs):
790  src = self.expr_fix_regs_for_mode(e.src)
791  dst = replace_regs[e.dst].arg
792  e = m2_expr.ExprAff(dst, src.zeroExtend(64))
793  irs[i] = self.expr_fix_regs_for_mode(e)
794  irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst)
795 
796  def mod_pc(self, instr, instr_ir, extra_ir):
797  "Replace PC by the instruction's offset"
798  cur_offset = m2_expr.ExprInt64(instr.offset)
799  for i, expr in enumerate(instr_ir):
800  dst, src = expr.dst, expr.src
801  if dst != self.pc:
802  dst = dst.replace_expr({self.pc: cur_offset})
803  src = src.replace_expr({self.pc: cur_offset})
804  instr_ir[i] = m2_expr.ExprAff(dst, src)
805  for b in extra_ir:
806  for irs in b.irs:
807  for i, expr in enumerate(irs):
808  dst, src = expr.dst, expr.src
809  if dst != self.pc:
810  dst = dst.replace_expr({self.pc: cur_offset})
811  src = src.replace_expr({self.pc: cur_offset})
812  irs[i] = m2_expr.ExprAff(dst, src)
813 
814 
815  def del_dst_zr(self, instr, instr_ir, extra_ir):
816  "Writes to zero register are discarded"
817  regs_to_fix = [WZR, XZR]
818  instr_ir = [expr for expr in instr_ir if expr.dst not in regs_to_fix]
819 
820  for b in extra_ir:
821  for i, irs in enumerate(b.irs):
822  b.irs[i] = [expr for expr in irs if expr.dst not in regs_to_fix]
823 
824  return instr_ir, extra_ir
825 
826 
828 
829  def __init__(self, symbol_pool=None):
830  ir.__init__(self, mn_aarch64, "b", symbol_pool)
831  self.pc = PC
832  self.sp = SP
833  self.IRDst = m2_expr.ExprId('IRDst', 64)
def update_flag_sub_of
Definition: sem.py:72
def update_flag_add_of
Definition: sem.py:60
def update_flag_sub_cf
Definition: sem.py:66
def update_flag_add_cf
Definition: sem.py:55