Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
arch.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 
4 import logging
5 from pyparsing import *
7 from miasm2.core.cpu import *
8 from collections import defaultdict
9 from miasm2.core.bin_stream import bin_stream
10 import miasm2.arch.msp430.regs as regs_module
11 from miasm2.arch.msp430.regs import *
12 from miasm2.core.asmbloc import asm_label
13 
14 log = logging.getLogger("msp430dis")
15 console_handler = logging.StreamHandler()
16 console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
17 log.addHandler(console_handler)
18 log.setLevel(logging.DEBUG)
19 
20 conditional_branch = ['jnz', 'jz', 'jnc', 'jc',
21  'jn', 'jge', 'jl']
22 unconditional_branch = ['jmp']
23 
24 def deref2expr_nooff(s, l, t):
25  t = t[0]
26  if len(t) == 1 and isinstance(t[0], ExprId):
27  return ExprMem(t[0], 16)
28  elif len(t) == 1 and isinstance(t[0], ExprInt):
29  return ExprMem(t[0], 16)
30  raise NotImplementedError('not fully functional')
31 
32 
33 def deref2expr_pinc(s, l, t):
34  t = t[0]
35  if len(t) == 1 and isinstance(t[0], ExprId):
36  return ExprOp('autoinc', t[0])
37  raise NotImplementedError('not fully functional')
38 
39 
40 def deref2expr_off(s, l, t):
41  t = t[0]
42  if len(t) == 2 and isinstance(t[1], ExprId):
43  return ExprMem(t[1] + t[0], 16)
44  raise NotImplementedError('not fully functional')
45 
46 
47 def deref_expr(s, l, t):
48  t = t[0]
49  assert(len(t) == 1)
50  t = t[0]
51  if isinstance(t, ExprId) or \
52  isinstance(t, ExprInt) or \
53  isinstance(t, ExprMem) or \
54  (isinstance(t, ExprOp) and t.op == "autoinc"):
55  return t
56 
57  raise NotImplementedError('not fully functional')
58 
59 
60 def f_reg2expr(t):
61  t = t[0]
62  i = regs16_str.index(t)
63  r = regs16_expr[i]
64  return r
65 
66 # gpregs.parser.setParseAction(f_reg2expr)
67 
68 ARO = Suppress("@")
69 LPARENT = Suppress("(")
70 RPARENT = Suppress(")")
71 
72 PINC = Suppress("+")
73 
74 
75 def ast_id2expr(t):
76  if not t in mn_msp430.regs.all_regs_ids_byname:
77  r = ExprId(asm_label(t), 16)
78  else:
79  r = mn_msp430.regs.all_regs_ids_byname[t]
80  return r
81 
82 
83 def ast_int2expr(a):
84  return ExprInt16(a)
85 
86 
87 variable, operand, base_expr = gen_base_expr()
88 
89 my_var_parser = parse_ast(ast_id2expr, ast_int2expr)
90 base_expr.setParseAction(my_var_parser)
91 
92 
93 deref_nooff = Group(ARO + base_expr).setParseAction(deref2expr_nooff)
94 deref_pinc = Group(ARO + base_expr + PINC).setParseAction(deref2expr_pinc)
95 deref_off = Group(base_expr + LPARENT +
96  gpregs.parser + RPARENT).setParseAction(deref2expr_off)
97 
98 
99 sreg_p = Group(deref_pinc | deref_nooff |
100  deref_off | base_expr).setParseAction(deref_expr)
101 
102 
104 
105  def __init__(self):
106  self.except_on_instr = False
107 
108 
110  delayslot = 0
111 
112  def dstflow(self):
113  if self.name.startswith('j'):
114  return True
115  return self.name in ['call']
116 
117  @staticmethod
118  def arg2str(e, pos = None):
119  if isinstance(e, ExprId):
120  o = str(e)
121  elif isinstance(e, ExprInt):
122  o = str(e)
123  elif isinstance(e, ExprOp) and e.op == "autoinc":
124  o = "@%s+" % str(e.args[0])
125  elif isinstance(e, ExprMem):
126  if isinstance(e.arg, ExprId):
127  if pos == 0:
128  o = "@%s" % e.arg
129  else:
130  o = "0x0(%s)" % e.arg
131  elif isinstance(e.arg, ExprInt):
132  o = "@%s" % e.arg
133  elif isinstance(e.arg, ExprOp):
134  o = "%s(%s)" % (e.arg.args[1], e.arg.args[0])
135  else:
136  raise NotImplementedError('unknown instance e = %s' % type(e))
137  return o
138 
139 
140  def dstflow2label(self, symbol_pool):
141  e = self.args[0]
142  if not isinstance(e, ExprInt):
143  return
144  if self.name == "call":
145  ad = e.arg
146  else:
147  ad = e.arg + int(self.offset)
148 
149  l = symbol_pool.getby_offset_create(ad)
150  s = ExprId(l, e.size)
151  self.args[0] = s
152 
153  def breakflow(self):
154  if self.name in conditional_branch + unconditional_branch:
155  return True
156  if self.name.startswith('ret'):
157  return True
158  if self.name.startswith('int'):
159  return True
160  if self.name.startswith('mov') and self.args[1] == PC:
161  return True
162  return self.name in ['call']
163 
164  def splitflow(self):
165  if self.name in conditional_branch:
166  return True
167  if self.name in unconditional_branch:
168  return False
169  return self.name in ['call']
170 
171  def setdstflow(self, a):
172  return
173 
174  def is_subcall(self):
175  return self.name in ['call']
176 
177  def getdstflow(self, symbol_pool):
178  return [self.args[0]]
179 
180  def get_symbol_size(self, symbol, symbol_pool):
181  return 16
182 
183  def fixDstOffset(self):
184  e = self.args[0]
185  if self.offset is None:
186  raise ValueError('symbol not resolved %s' % l)
187  if not isinstance(e, ExprInt):
188  # raise ValueError('dst must be int or label')
189  log.warning('dynamic dst %r', e)
190  return
191 
192  # Call argument is an absolute offset
193  # Other offsets are relative to instruction offset
194  if self.name != "call":
195  self.args[0] = ExprInt(int(e.arg) - self.offset, 16)
196 
197  def get_info(self, c):
198  pass
199 
200  def __str__(self):
201  o = super(instruction_msp430, self).__str__()
202  return o
203 
204  def get_args_expr(self):
205  args = []
206  for a in self.args:
207  args.append(a)
208  return args
209 
210 
211 mode_msp430 = None
212 
213 
215  name = "msp430"
216  regs = regs_module
217  all_mn = []
218  bintree = {}
219  num = 0
220  delayslot = 0
221  pc = {None: PC}
222  sp = {None: SP}
223  all_mn_mode = defaultdict(list)
224  all_mn_name = defaultdict(list)
225  all_mn_inst = defaultdict(list)
226  instruction = instruction_msp430
227  max_instruction_len = 8
228 
229  @classmethod
230  def getpc(cls, attrib):
231  return PC
232 
233  @classmethod
234  def getsp(cls, attrib):
235  return SP
236 
237  @classmethod
238  def check_mnemo(cls, fields):
239  l = sum([x.l for x in fields])
240  assert l % 16 == 00, "len %r" % l
241 
242  @classmethod
243  def getbits(cls, bs, attrib, start, n):
244  if not n:
245  return 0
246  o = 0
247  if n > bs.getlen() * 8:
248  raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
249  while n:
250  i = start / 8
251  c = cls.getbytes(bs, i)
252  if not c:
253  raise IOError
254  c = ord(c)
255  r = 8 - start % 8
256  c &= (1 << r) - 1
257  l = min(r, n)
258  c >>= (r - l)
259  o <<= l
260  o |= c
261  n -= l
262  start += l
263  return o
264 
265  @classmethod
266  def getbytes(cls, bs, offset, l=1):
267  out = ""
268  for _ in xrange(l):
269  n_offset = (offset & ~1) + 1 - offset % 2
270  out += bs.getbytes(n_offset, 1)
271  offset += 1
272  return out
273 
274  def decoded2bytes(self, result):
275  tmp = super(mn_msp430, self).decoded2bytes(result)
276  out = []
277  for x in tmp:
278  o = ""
279  while x:
280  o += x[:2][::-1]
281  x = x[2:]
282  out.append(o)
283  return out
284 
285  @classmethod
286  def gen_modes(cls, subcls, name, bases, dct, fields):
287  dct['mode'] = None
288  return [(subcls, name, bases, dct, fields)]
289 
290  def additional_info(self):
291  info = additional_info()
292  return info
293 
294  @classmethod
295  def getmn(cls, name):
296  return name.upper()
297 
298  def reset_class(self):
299  super(mn_msp430, self).reset_class()
300 
301  def getnextflow(self, symbol_pool):
302  raise NotImplementedError('not fully functional')
303 
304 
305 def addop(name, fields, args=None, alias=False):
306  dct = {"fields": fields}
307  dct["alias"] = alias
308  if args is not None:
309  dct['args'] = args
310  type(name, (mn_msp430,), dct)
311 
312 
314  prio = 5
315  mn_mod = ['.w', '.b']
316 
317 
319  prio = default_prio + 1
320  reg_info = gpregs
321  parser = sreg_p
322 
323  def decode(self, v):
324  size = 16
325  if hasattr(self.parent, 'size'):
326  size = [16, 8][self.parent.size.value]
327  v = v & self.lmask
328  e = self.reg_info.expr[v]
329  if self.parent.a_s.value == 0b00:
330  if e == R3:
331  self.expr = ExprInt(0, size)
332  else:
333  self.expr = e
334  elif self.parent.a_s.value == 0b01:
335  if e == SR:
336  self.expr = ExprMem(ExprInt16(self.parent.off_s.value), size)
337  elif e == R3:
338  self.expr = ExprInt(1, size)
339  else:
340  self.expr = ExprMem(
341  e + ExprInt16(self.parent.off_s.value), size)
342  elif self.parent.a_s.value == 0b10:
343  if e == SR:
344  self.expr = ExprInt(4, size)
345  elif e == R3:
346  self.expr = ExprInt(2, size)
347  else:
348  self.expr = ExprMem(e, size)
349  elif self.parent.a_s.value == 0b11:
350  if e == SR:
351  self.expr = ExprInt(8, size)
352  elif e == R3:
353  if self.parent.size.value == 0:
354  self.expr = ExprInt(0xffff, size)
355  else:
356  self.expr = ExprInt(0xff, size)
357  elif e == PC:
358  self.expr = ExprInt(self.parent.off_s.value, size)
359  else:
360  self.expr = ExprOp('autoinc', e)
361  else:
362  raise NotImplementedError(
363  "unknown value self.parent.a_s.value = " +
364  "%d" % self.parent.a_s.value)
365  return True
366 
367  def encode(self):
368  e = self.expr
369  if e in self.reg_info.expr:
370  self.parent.a_s.value = 0
371  self.value = self.reg_info.expr.index(e)
372  elif isinstance(e, ExprInt):
373  v = int(e.arg)
374  if v == 0xffff and self.parent.size.value == 0:
375  self.parent.a_s.value = 0b11
376  self.value = 3
377  elif v == 0xff and self.parent.size.value == 1:
378  self.parent.a_s.value = 0b11
379  self.value = 3
380  elif v == 2:
381  self.parent.a_s.value = 0b10
382  self.value = 3
383  elif v == 1:
384  self.parent.a_s.value = 0b01
385  self.value = 3
386  elif v == 8:
387  self.parent.a_s.value = 0b11
388  self.value = 2
389  elif v == 4:
390  self.parent.a_s.value = 0b10
391  self.value = 2
392  elif v == 0:
393  self.parent.a_s.value = 0b00
394  self.value = 3
395  else:
396  self.parent.a_s.value = 0b11
397  self.value = 0
398  self.parent.off_s.value = v
399  elif isinstance(e, ExprMem):
400  if isinstance(e.arg, ExprId):
401  self.parent.a_s.value = 0b10
402  self.value = self.reg_info.expr.index(e.arg)
403  elif isinstance(e.arg, ExprInt):
404  self.parent.a_s.value = 0b01
405  self.value = self.reg_info.expr.index(SR)
406  self.parent.off_s.value = int(e.arg.arg)
407  elif isinstance(e.arg, ExprOp):
408  self.parent.a_s.value = 0b01
409  self.value = self.reg_info.expr.index(e.arg.args[0])
410  self.parent.off_s.value = int(e.arg.args[1].arg)
411  else:
412  raise NotImplementedError(
413  'unknown instance e.arg = %s' % type(e.arg))
414  elif isinstance(e, ExprOp) and e.op == "autoinc":
415  self.parent.a_s.value = 0b11
416  self.value = self.reg_info.expr.index(e.args[0])
417  else:
418  raise NotImplementedError('unknown instance e = %s' % type(e))
419  return True
420 
421 
423  prio = default_prio + 1
424  reg_info = gpregs
425  parser = sreg_p
426 
427  def decode(self, v):
428  if hasattr(self.parent, 'size'):
429  size = [16, 8][self.parent.size.value]
430  else:
431  size = 16
432 
433  v = v & self.lmask
434  e = self.reg_info.expr[v]
435  if self.parent.a_d.value == 0:
436  self.expr = e
437  elif self.parent.a_d.value == 1:
438  if e == SR:
439  x = ExprInt16(self.parent.off_d.value)
440  else:
441  x = e + ExprInt16(self.parent.off_d.value)
442  self.expr = ExprMem(x, size)
443  else:
444  raise NotImplementedError(
445  "unknown value self.parent.a_d.value = " +
446  "%d" % self.parent.a_d.value)
447  return True
448 
449  def encode(self):
450  e = self.expr
451  if e in self.reg_info.expr:
452  self.parent.a_d.value = 0
453  self.value = self.reg_info.expr.index(e)
454  elif isinstance(e, ExprMem):
455  if isinstance(e.arg, ExprId):
456  r, i = e.arg, ExprInt16(0)
457  elif isinstance(e.arg, ExprOp):
458  r, i = e.arg.args[0], e.arg.args[1]
459  elif isinstance(e.arg, ExprInt):
460  r, i = SR, e.arg
461  else:
462  raise NotImplementedError(
463  'unknown instance e.arg = %s' % type(e.arg))
464  self.parent.a_d.value = 1
465  self.value = self.reg_info.expr.index(r)
466  self.parent.off_d.value = int(i.arg)
467  else:
468  raise NotImplementedError('unknown instance e = %s' % type(e))
469  return True
470 
472 
473  @classmethod
474  def flen(cls, mode, v):
475  if v['a_s'] == 0b00:
476  return None
477  elif v['a_s'] == 0b01:
478  if v['sreg'] in [3]:
479  return None
480  else:
481  return 16
482  elif v['a_s'] == 0b10:
483  return None
484  elif v['a_s'] == 0b11:
485  """
486  if v['sreg'] in [2, 3]:
487  return None
488  else:
489  return 16
490  """
491  if v['sreg'] in [0]:
492  return 16
493  else:
494  return None
495  else:
496  raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s'])
497 
498  def encode(self):
499  return super(bs_cond_off_s, self).encode()
500 
501  def decode(self, v):
502  if self.l == 0:
503  self.value = None
504  self.value = v
505  return True
506 
507 
509 
510  @classmethod
511  def flen(cls, mode, v):
512  if v['a_d'] == 0:
513  return None
514  elif v['a_d'] == 1:
515  return 16
516  else:
517  raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])
518 
519 
521  parser = base_expr
522 
523  def int2expr(self, v):
524  if v & ~self.intmask != 0:
525  return None
526  return ExprInt(v, 16)
527 
528  def decodeval(self, v):
529  v <<= 1
530  v += self.parent.l
531  return v
532 
533  def encodeval(self, v):
534  plen = self.parent.l + self.l
535  assert(plen % 8 == 0)
536  v -= plen / 8
537  if v % 2 != 0:
538  return False
539  return v >> 1
540 
541  def decode(self, v):
542  v = v & self.lmask
543  if (1 << (self.l - 1)) & v:
544  v |= ~0 ^ self.lmask
545  v = self.decodeval(v)
546  self.expr = ExprInt16(v)
547  return True
548 
549  def encode(self):
550  if not isinstance(self.expr, ExprInt):
551  return False
552  v = int(self.expr.arg)
553  if (1 << (self.l - 1)) & v:
554  v = -((0xffff ^ v) + 1)
555  v = self.encodeval(v)
556  self.value = (v & 0xffff) & self.lmask
557  return True
558 
559 
560 off_s = bs(l=16, order=-10, cls=(bs_cond_off_s,), fname = "off_s")
561 off_d = bs(l=16, order=-10, cls=(bs_cond_off_d,), fname = "off_d")
562 
563 a_s = bs(l=2, order=-4, fname='a_s')
564 a_d = bs(l=1, order=-6, fname='a_d')
565 
566 a_d2 = bs(l=2, order=-2, fname='a_d')
567 
568 sreg = bs(l=4, order=-3, cls=(msp430_sreg_arg,), fname='sreg')
569 dreg = bs(l=4, order=-5, cls=(msp430_dreg_arg,), fname='dreg')
570 
571 bw = bw_mn(l=1, order=-10, mn_mod=['.w', '.b'], fname='size')
572 
573 bs_f1 = bs_name(
574  l=4, name={
575  'mov': 4, 'add': 5, 'addc': 6, 'subc': 7, 'sub': 8, 'cmp': 9,
576  'dadd': 10, 'bit': 11, 'bic': 12, 'bis': 13, 'xor': 14, 'and': 15})
577 addop("f1", [bs_f1, sreg, a_d, bw, a_s, dreg, off_s, off_d])
578 
579 bs_f2 = bs_name(l=3, name={'rrc': 0, 'rra': 2,
580  'push': 4})
581 addop("f2_1", [bs('000100'), bs_f2, bw, a_s, sreg, off_s])
582 
583 
584 bs_f2_nobw = bs_name(l=3, name={'swpb': 1, 'sxt': 3,
585  'call': 5})
586 addop("f2_2", [bs('000100'), bs_f2_nobw, bs('0'), a_s, sreg, off_s])
587 
588 # Offset must be decoded in last position to have final instruction len
589 offimm = bs(l=10, cls=(msp430_offs,), fname="offs", order=-1)
590 
591 bs_f2_jcc = bs_name(l=3, name={'jnz': 0, 'jz': 1, 'jnc': 2, 'jc': 3, 'jn': 4,
592  'jge': 5, 'jl': 6, 'jmp': 7})
593 addop("f2_3", [bs('001'), bs_f2_jcc, offimm])
594 
def gen_base_expr
Definition: cpu.py:309