Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
cpu.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 
4 import re
5 import struct
6 import logging
7 from collections import defaultdict
8 
9 import pyparsing
10 
11 import miasm2.expression.expression as m2_expr
12 from miasm2.core import asmbloc
13 from miasm2.core.bin_stream import bin_stream, bin_stream_str
14 from miasm2.core.utils import Disasm_Exception
15 from miasm2.expression.simplifications import expr_simp
16 
17 log = logging.getLogger("cpuhelper")
18 console_handler = logging.StreamHandler()
19 console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
20 log.addHandler(console_handler)
21 log.setLevel(logging.WARN)
22 
23 
24 class bitobj:
25 
26  def __init__(self, s=""):
27  if not s:
28  bits = []
29  else:
30  bits = list(bin(int(str(s).encode('hex'), 16))[2:])
31  bits = [int(x) for x in bits]
32  if len(bits) % 8:
33  bits = [0 for x in xrange(8 - (len(bits) % 8))] + bits
34  bits = ['0' for x in xrange(len(s) * 8 - len(bits))] + bits
35  self.bits = bits
36  self.offset = 0
37 
38  def __len__(self):
39  return len(self.bits) - self.offset
40 
41  def getbits(self, n):
42  if not n:
43  return 0
44  o = 0
45  if n > len(self.bits) - self.offset:
46  raise ValueError('not enought bits %r %r' % (n, len(self.bits)))
47  b = self.bits[self.offset:self.offset + n]
48  b = int("".join([str(x) for x in b]), 2)
49  self.offset += n
50  return b
51 
52  def putbits(self, b, n):
53  if not n:
54  return
55  bits = list(bin(b)[2:])
56  bits = [int(x) for x in bits]
57  bits = [0 for x in xrange(n - len(bits))] + bits
58  self.bits += bits
59 
60  def tostring(self):
61  if len(self.bits) % 8:
62  raise ValueError(
63  'num bits must be 8 bit aligned: %d' % len(self.bits))
64  b = int("".join([str(x) for x in self.bits]), 2)
65  b = "%X" % b
66  b = '0' * (len(self.bits) / 4 - len(b)) + b
67  b = b.decode('hex')
68  return b
69 
70  def reset(self):
71  self.offset = 0
72 
73  def copy_state(self):
74  b = self.__class__()
75  b.bits = self.bits
76  b.offset = self.offset
77  return b
78 
79 
80 def literal_list(l):
81  l = l[:]
82  l.sort()
83  l = l[::-1]
84  o = pyparsing.Literal(l[0])
85  for x in l[1:]:
86  o |= pyparsing.Literal(x)
87  return o
88 
89 
90 class reg_info:
91 
92  def __init__(self, reg_str, reg_expr):
93  self.str = reg_str
94  self.expr = reg_expr
95  self.parser = literal_list(reg_str).setParseAction(self.reg2expr)
96 
97  def reg2expr(self, s):
98  i = self.str.index(s[0])
99  return self.expr[i]
100 
101  def expr2regi(self, e):
102  return self.expr.index(e)
103 
104 
105 def gen_reg(rname, env, sz=32):
106  """
107  Gen reg expr and parser
108  Equivalent to:
109  PC = ExprId('PC')
110  reg_pc_str = ['PC']
111  reg_pc_expr = [ExprId(x, sz) for x in reg_pc_str]
112  regpc = reg_info(reg_pc_str, reg_pc_expr)
113 
114  class bs_rname(m_reg):
115  reg = regi_rname
116 
117  bsrname = bs(l=0, cls=(bs_rname,))
118 
119  """
120  rnamel = rname.lower()
121  r = m2_expr.ExprId(rname, sz)
122  reg_str = [rname]
123  reg_expr = [r]
124  regi = reg_info(reg_str, reg_expr)
125  # define as global val
126  cname = "bs_" + rnamel
127  c = type(cname, (m_reg,), {'reg': regi})
128  env[rname] = r
129  env["regi_" + rnamel] = regi
130  env[cname] = c
131  env["bs" + rnamel] = bs(l=0, cls=(c,))
132  return r, regi
133 
134 
135 def gen_regs(rnames, env, sz=32):
136  regs_str = []
137  regs_expr = []
138  regs_init = []
139  for rname in rnames:
140  r = m2_expr.ExprId(rname, sz)
141  r_init = m2_expr.ExprId(rname+'_init', sz)
142  regs_str.append(rname)
143  regs_expr.append(r)
144  regs_init.append(r_init)
145  env[rname] = r
146 
147  reginfo = reg_info(regs_str, regs_expr)
148  return regs_expr, regs_init, reginfo
149 
150 
151 LPARENTHESIS = pyparsing.Literal("(")
152 RPARENTHESIS = pyparsing.Literal(")")
153 
154 
155 def int2expr(t):
156  v = t[0]
157  return (m2_expr.ExprInt, v)
158 
159 
160 def parse_op(t):
161  v = t[0]
162  return (m2_expr.ExprOp, v)
163 
164 
165 def parse_id(t):
166  v = t[0]
167  return (m2_expr.ExprId, v)
168 
169 
171  if len(t) == 1:
172  return t[0]
173  if len(t) == 2:
174  if t[0] in ['-', '+', '!']:
175  return m2_expr.ExprOp(t[0], t[1])
176  if len(t) == 3:
177  args = [t[0], t[2]]
178  if t[1] == '-':
179  # a - b => a + (-b)
180  t[1] = '+'
181  t[2] = - t[2]
182  return m2_expr.ExprOp(t[1], t[0], t[2])
183  t = t[::-1]
184  while len(t) >= 3:
185  o1, op, o2 = t.pop(), t.pop(), t.pop()
186  if op == '-':
187  # a - b => a + (-b)
188  op = '+'
189  o2 = - o2
190  e = m2_expr.ExprOp(op, o1, o2)
191  t.append(e)
192  if len(t) != 1:
193  raise NotImplementedError('strange op')
194  return t[0]
195 
196 
197 def ast_id2expr(a):
198  return m2_expr.ExprId(a, 32)
199 
200 
202  return m2_expr.ExprInt32(a)
203 
204 
205 def ast_raw2expr(a, my_id2expr, my_int2expr):
206  assert(isinstance(a, tuple))
207  if a[0] is m2_expr.ExprId:
208  e = my_id2expr(a[1])
209  elif a[0] is m2_expr.ExprInt:
210  e = my_int2expr(a[1])
211  elif a[0] is m2_expr.ExprOp:
212  out = []
213  for x in a[1]:
214  if isinstance(x, tuple):
215  x = ast_raw2expr(x, my_id2expr, my_int2expr)
216  out.append(x)
217  e = ast_parse_op(out)
218  else:
219  raise TypeError('unknown type')
220  return e
221 
222 
223 def ast_get_ids(a):
224  assert(isinstance(a, tuple))
225  if a[0] is m2_expr.ExprId:
226  return set([a[1]])
227  elif a[0] is m2_expr.ExprInt:
228  return set()
229  elif a[0] is m2_expr.ExprOp:
230  out = set()
231  for x in a[1]:
232  if isinstance(x, tuple):
233  out.update(ast_get_ids(x))
234  return out
235  raise TypeError('unknown type')
236 
237 
239  assert(isinstance(a, tuple))
240  if a[0] in [m2_expr.ExprInt, m2_expr.ExprId]:
241  return a
242  elif a[0] is m2_expr.ExprOp:
243  out = []
244  for x in a[1]:
245  if isinstance(x, tuple):
246  x = _extract_ast_core(x)
247  out.append(x)
248  return tuple([a[0]] + [out])
249  else:
250  raise TypeError('unknown type')
251 
252 
253 def extract_ast_core(v, my_id2expr, my_int2expr):
254  ast_tokens = _extract_ast_core(v)
255  ids = ast_get_ids(ast_tokens)
256  ids_expr = [my_id2expr(x) for x in ids]
257  sizes = set([i.size for i in ids_expr])
258 
259  if len(sizes) == 0:
260  pass
261  elif len(sizes) == 1:
262  size = sizes.pop()
263  my_int2expr = lambda x: m2_expr.ExprInt(x, size)
264  else:
265  raise ValueError('multiple sizes in ids')
266  e = ast_raw2expr(ast_tokens, my_id2expr, my_int2expr)
267  return e
268 
269 
270 class parse_ast:
271 
272  def __init__(self, id2expr, int2expr, extract_ast=extract_ast_core):
273  self.id2expr = id2expr
274  self.int2expr = int2expr
275  self.extract_ast_core = extract_ast
276 
277  def __call__(self, v):
278  v = v[0]
279  if isinstance(v, m2_expr.Expr):
280  return v
281  return self.extract_ast_core(v, self.id2expr, self.int2expr)
282 
283 
284 def neg_int(t):
285  x = -t[0]
286  return x
287 
288 
289 integer = pyparsing.Word(pyparsing.nums).setParseAction(lambda _a, _b, t:
290  int(t[0]))
291 hex_word = pyparsing.Literal('0x') + pyparsing.Word(pyparsing.hexnums)
292 hex_int = pyparsing.Combine(hex_word).setParseAction(lambda _a, _b, t:
293  int(t[0], 16))
294 
295 # str_int = (Optional('-') + (hex_int | integer))
296 str_int_pos = (hex_int | integer)
297 str_int_neg = (pyparsing.Suppress('-') + \
298  (hex_int | integer)).setParseAction(neg_int)
299 
300 str_int = str_int_pos | str_int_neg
301 str_int.setParseAction(int2expr)
302 
303 logicop = pyparsing.oneOf('& | ^ >> << <<< >>>')
304 signop = pyparsing.oneOf('+ -')
305 multop = pyparsing.oneOf('* / %')
306 plusop = pyparsing.oneOf('+ -')
307 
308 
310  variable = pyparsing.Word(pyparsing.alphas + "_$.",
311  pyparsing.alphanums + "_")
312  variable.setParseAction(parse_id)
313  operand = str_int | variable
314  base_expr = pyparsing.operatorPrecedence(operand,
315  [("!", 1, pyparsing.opAssoc.RIGHT, parse_op),
316  (logicop, 2, pyparsing.opAssoc.RIGHT,
317  parse_op),
318  (signop, 1, pyparsing.opAssoc.RIGHT,
319  parse_op),
320  (multop, 2, pyparsing.opAssoc.LEFT,
321  parse_op),
322  (plusop, 2, pyparsing.opAssoc.LEFT,
323  parse_op),
324  ])
325  return variable, operand, base_expr
326 
327 
328 variable, operand, base_expr = gen_base_expr()
329 
330 my_var_parser = parse_ast(ast_id2expr, ast_int2expr)
331 base_expr.setParseAction(my_var_parser)
332 
333 default_prio = 0x1337
334 
335 
336 def isbin(s):
337  return re.match('[0-1]+$', s)
338 
339 
340 def int2bin(i, l):
341  s = '0' * l + bin(i)[2:]
342  return s[-l:]
343 
344 
345 def myror32(v, r):
346  return ((v & 0xFFFFFFFFL) >> r) | ((v << (32 - r)) & 0xFFFFFFFFL)
347 
348 
349 def myrol32(v, r):
350  return ((v & 0xFFFFFFFFL) >> (32 - r)) | ((v << r) & 0xFFFFFFFFL)
351 
352 
353 class bs(object):
354  all_new_c = {}
355  prio = default_prio
356 
357  def __init__(self, strbits=None, l=None, cls=None,
358  fname=None, order=0, flen=None, **kargs):
359  if fname is None:
360  fname = hex(id(str((strbits, l, cls, fname, order, flen, kargs))))
361  if strbits is None:
362  strbits = "" # "X"*l
363  elif l is None:
364  l = len(strbits)
365  if strbits and isbin(strbits):
366  value = int(strbits, 2)
367  elif 'default_val' in kargs:
368  value = int(kargs['default_val'], 2)
369  else:
370  value = None
371  allbits = list(strbits)
372  allbits.reverse()
373  fbits = 0
374  fmask = 0
375  while allbits:
376  a = allbits.pop()
377  if a == " ":
378  continue
379  fbits <<= 1
380  fmask <<= 1
381  if a in '01':
382  a = int(a)
383  fbits |= a
384  fmask |= 1
385  lmask = (1 << l) - 1
386  # gen conditional field
387  if cls:
388  for b in cls:
389  if 'flen' in b.__dict__:
390  flen = getattr(b, 'flen')
391 
392  self.strbits = strbits
393  self.l = l
394  self.cls = cls
395  self.fname = fname
396  self.order = order
397  self.lmask = lmask
398  self.fbits = fbits
399  self.fmask = fmask
400  self.flen = flen
401  self.value = value
402  self.kargs = kargs
403 
404  def __getitem__(self, item):
405  return getattr(self, item)
406 
407  def __repr__(self):
408  o = self.__class__.__name__
409  if self.fname:
410  o += "_%s" % self.fname
411  o += "_%(strbits)s" % self
412  if self.cls:
413  o += '_' + '_'.join([x.__name__ for x in self.cls])
414  return o
415 
416  def gen(self, parent):
417  c_name = 'nbsi'
418  if self.cls:
419  c_name += '_' + '_'.join([x.__name__ for x in self.cls])
420  bases = list(self.cls)
421  else:
422  bases = []
423  # bsi added at end of list
424  # used to use first function of added class
425  bases += [bsi]
426  k = c_name, tuple(bases)
427  if k in self.all_new_c:
428  new_c = self.all_new_c[k]
429  else:
430  new_c = type(c_name, tuple(bases), {})
431  self.all_new_c[k] = new_c
432  c = new_c(parent,
433  self.strbits, self.l, self.cls,
434  self.fname, self.order, self.lmask, self.fbits,
435  self.fmask, self.value, self.flen, **self.kargs)
436  return c
437 
438  def check_fbits(self, v):
439  return v & self.fmask == self.fbits
440 
441  @classmethod
442  def flen(cls, v):
443  raise NotImplementedError('not fully functional')
444 
445 
447 
448  def __init__(self, e=None):
449  self.expr = e
450 
451 
452 class bsopt(bs):
453 
454  def ispresent(self):
455  return True
456 
457 
458 class bsi(object):
459 
460  def __init__(self, parent, strbits, l, cls, fname, order,
461  lmask, fbits, fmask, value, flen, **kargs):
462  self.parent = parent
463  self.strbits = strbits
464  self.l = l
465  self.cls = cls
466  self.fname = fname
467  self.order = order
468  self.lmask = lmask
469  self.fbits = fbits
470  self.fmask = fmask
471  self.flen = flen
472  self.value = value
473  self.kargs = kargs
474  self.__dict__.update(self.kargs)
475 
476  def decode(self, v):
477  self.value = v & self.lmask
478  return True
479 
480  def encode(self):
481  return True
482 
483  def clone(self):
484  s = self.__class__(self.parent,
485  self.strbits, self.l, self.cls,
486  self.fname, self.order, self.lmask, self.fbits,
487  self.fmask, self.value, self.flen, **self.kargs)
488  s.__dict__.update(self.kargs)
489  if hasattr(self, 'expr'):
490  s.expr = self.expr
491  return s
492 
493  def __hash__(self):
494  kargs = []
495  for k, v in self.kargs.items():
496  if isinstance(v, list):
497  v = tuple(v)
498  kargs.append((k, v))
499  l = [self.strbits, self.l, self.cls,
500  self.fname, self.order, self.lmask, self.fbits,
501  self.fmask, self.value] # + kargs
502 
503  return hash(tuple(l))
504 
505 
507  prio = default_prio
508 
509  def __init__(self, **kargs):
510  self.args = kargs
511 
512  def __getattr__(self, item):
513  if item in self.__dict__:
514  return self.__dict__[item]
515  elif item in self.args:
516  return self.args.get(item)
517  else:
518  raise AttributeError
519 
520 
522  prio = 1
523 
524  def divert(self, i, candidates):
525  out = []
526  for candidate in candidates:
527  cls, name, bases, dct, fields = candidate
528  for new_name, value in self.args['name'].items():
529  nfields = fields[:]
530  s = int2bin(value, self.args['l'])
531  args = dict(self.args)
532  args.update({'strbits': s})
533  f = bs(**args)
534  nfields[i] = f
535  ndct = dict(dct)
536  ndct['name'] = new_name
537  out.append((cls, new_name, bases, ndct, nfields))
538  return out
539 
540 
542  prio = 2
543 
544  def divert(self, i, candidates):
545  out = []
546  for candidate in candidates:
547  cls, name, bases, dct, fields = candidate
548  tab = self.args['mn_mod']
549  if isinstance(tab, list):
550  tmp = {}
551  for j, v in enumerate(tab):
552  tmp[j] = v
553  tab = tmp
554  for value, new_name in tab.items():
555  nfields = fields[:]
556  s = int2bin(value, self.args['l'])
557  args = dict(self.args)
558  args.update({'strbits': s})
559  f = bs(**args)
560  nfields[i] = f
561  ndct = dict(dct)
562  ndct['name'] = self.modname(ndct['name'], value)
563  out.append((cls, new_name, bases, ndct, nfields))
564  return out
565 
566  def modname(self, name, i):
567  return name + self.args['mn_mod'][i]
568 
569 
570 class bs_cond(bsi):
571  pass
572 
573 
574 class bs_swapargs(bs_divert):
575 
576  def divert(self, i, candidates):
577  out = []
578  for cls, name, bases, dct, fields in candidates:
579  # args not permuted
580  ndct = dict(dct)
581  nfields = fields[:]
582  # gen fix field
583  f = gen_bsint(0, self.args['l'], self.args)
584  nfields[i] = f
585  out.append((cls, name, bases, ndct, nfields))
586 
587  # args permuted
588  ndct = dict(dct)
589  nfields = fields[:]
590  ap = ndct['args_permut'][:]
591  a = ap.pop(0)
592  b = ap.pop(0)
593  ndct['args_permut'] = [b, a] + ap
594  # gen fix field
595  f = gen_bsint(1, self.args['l'], self.args)
596  nfields[i] = f
597 
598  out.append((cls, name, bases, ndct, nfields))
599  return out
600 
601 
602 class m_arg(object):
603 
604  def fromstring(self, s, parser_result=None):
605  if parser_result:
606  e, start, stop = parser_result[self.parser]
607  self.expr = e
608  return start, stop
609  try:
610  v, start, stop = self.parser.scanString(s).next()
611  except StopIteration:
612  return None, None
613  self.expr = v[0]
614  return start, stop
615 
616 
617 class m_reg(m_arg):
618  prio = default_prio
619 
620  @property
621  def parser(self):
622  return self.reg.parser
623 
624  def decode(self, v):
625  self.expr = self.reg.expr[0]
626  return True
627 
628  def encode(self):
629  return self.expr == self.reg.expr[0]
630 
631 
633  reg_info = None
634  parser = None
635 
636  def fromstring(self, s, parser_result=None):
637  if parser_result:
638  e, start, stop = parser_result[self.parser]
639  self.expr = e
640  return start, stop
641  try:
642  v, start, stop = self.parser.scanString(s).next()
643  except StopIteration:
644  return None, None
645  self.expr = v[0]
646  return start, stop
647 
648  def decode(self, v):
649  v = v & self.lmask
650  if v >= len(self.reg_info.expr):
651  return False
652  self.expr = self.reg_info.expr[v]
653  return True
654 
655  def encode(self):
656  if not self.expr in self.reg_info.expr:
657  log.debug("cannot encode reg %r", self.expr)
658  return False
659  self.value = self.reg_info.expr.index(self.expr)
660  if self.value > self.lmask:
661  log.debug("cannot encode field value %x %x",
662  self.value, self.lmask)
663  return False
664  return True
665 
666  def check_fbits(self, v):
667  return v & self.fmask == self.fbits
668 
669 
670 class mn_prefix:
671 
672  def __init__(self):
673  b = None
674 
675 
676 def swap16(v):
677  return struct.unpack('<H', struct.pack('>H', v))[0]
678 
679 
680 def swap32(v):
681  return struct.unpack('<I', struct.pack('>I', v))[0]
682 
683 
684 def perm_inv(p):
685  o = [None for x in xrange(len(p))]
686  for i, x in enumerate(p):
687  o[x] = i
688  return o
689 
690 
691 def gen_bsint(value, l, args):
692  s = int2bin(value, l)
693  args = dict(args)
694  args.update({'strbits': s})
695  f = bs(**args)
696  return f
697 
698 total_scans = 0
699 
700 
701 def branch2nodes(branch, nodes=None):
702  if nodes is None:
703  node = []
704  for k, v in branch.items():
705  if not isinstance(v, dict):
706  continue
707  for k2 in v.keys():
708  nodes.append((k, k2))
709  branch2nodes(v, nodes)
710 
711 
712 def factor_one_bit(tree):
713  if isinstance(tree, set):
714  return tree
715  new_keys = defaultdict(lambda: defaultdict(dict))
716  if len(tree) == 1:
717  return tree
718  for k, v in tree.items():
719  if k == "mn":
720  new_keys[k] = v
721  continue
722  l, fmask, fbits, fname, flen = k
723  if flen is not None or l <= 1:
724  new_keys[k] = v
725  continue
726  cfmask = fmask >> (l - 1)
727  nfmask = fmask & ((1 << (l - 1)) - 1)
728  cfbits = fbits >> (l - 1)
729  nfbits = fbits & ((1 << (l - 1)) - 1)
730  ck = 1, cfmask, cfbits, None, flen
731  nk = l - 1, nfmask, nfbits, fname, flen
732  if nk in new_keys[ck]:
733  raise NotImplementedError('not fully functional')
734  new_keys[ck][nk] = v
735  for k, v in new_keys.items():
736  new_keys[k] = factor_one_bit(v)
737  # try factor sons
738  if len(new_keys) != 1:
739  return new_keys
740  subtree = new_keys.values()[0]
741  if len(subtree) != 1:
742  return new_keys
743  if subtree.keys()[0] == 'mn':
744  return new_keys
745 
746  return new_keys
747 
748 
749 def factor_fields(tree):
750  if not isinstance(tree, dict):
751  return tree
752  if len(tree) != 1:
753  return tree
754  # merge
755  k1, v1 = tree.items()[0]
756  if k1 == "mn":
757  return tree
758  l1, fmask1, fbits1, fname1, flen1 = k1
759  if fname1 is not None:
760  return tree
761  if flen1 is not None:
762  return tree
763 
764  if not isinstance(v1, dict):
765  return tree
766  if len(v1) != 1:
767  return tree
768  k2, v2 = v1.items()[0]
769  if k2 == "mn":
770  return tree
771  l2, fmask2, fbits2, fname2, flen2 = k2
772  if fname2 is not None:
773  return tree
774  if flen2 is not None:
775  return tree
776  l = l1 + l2
777  fmask = (fmask1 << l2) | fmask2
778  fbits = (fbits1 << l2) | fbits2
779  fname = fname2
780  flen = flen2
781  k = l, fmask, fbits, fname, flen
782  new_keys = {k: v2}
783  return new_keys
784 
785 
787  if not isinstance(tree, dict):
788  return tree
789  new_keys = {}
790  for k, v in tree.items():
791  v = factor_fields(v)
792  new_keys[k] = factor_fields_all(v)
793  return new_keys
794 
795 
796 def factor_tree(tree):
797  new_keys = {}
798  i = 1
799  min_len = min([x[0] for x in tree.keys()])
800  while i < min_len:
801 
802  i += 1
803 
804 
805 def graph_tree(tree):
806  nodes = []
807  branch2nodes(tree, nodes)
808 
809  out = """
810  digraph G {
811  """
812  for a, b in nodes:
813  if b == 'mn':
814  continue
815  out += "%s -> %s;\n" % (id(a), id(b))
816  out += "}"
817  open('graph.txt', 'w').write(out)
818 
819 
821  branch = tree
822  for f in c.fields:
823  if f.l == 0:
824  continue
825  node = f.l, f.fmask, f.fbits, f.fname, f.flen
826 
827  if not node in branch:
828  branch[node] = {}
829  branch = branch[node]
830  if not 'mn' in branch:
831  branch['mn'] = set()
832  branch['mn'].add(c)
833 
834 
835 def add_candidate(bases, c):
836  add_candidate_to_tree(bases[0].bintree, c)
837 
838 
839 def getfieldby_name(fields, fname):
840  f = filter(lambda x: hasattr(x, 'fname') and x.fname == fname, fields)
841  if len(f) != 1:
842  raise ValueError('more than one field with name: %s' % fname)
843  return f[0]
844 
845 
846 def getfieldindexby_name(fields, fname):
847  for i, f in enumerate(fields):
848  if hasattr(f, 'fname') and f.fname == fname:
849  return f, i
850  return None
851 
852 
853 class metamn(type):
854 
855  def __new__(mcs, name, bases, dct):
856  if name == "cls_mn" or name.startswith('mn_'):
857  return type.__new__(mcs, name, bases, dct)
858  alias = dct.get('alias', False)
859 
860  fields = bases[0].mod_fields(dct['fields'])
861  if not 'name' in dct:
862  dct["name"] = bases[0].getmn(name)
863  if 'args' in dct:
864  # special case for permuted arguments
865  o = []
866  p = []
867  for i, a in enumerate(dct['args']):
868  o.append((i, a))
869  if a in fields:
870  p.append((fields.index(a), a))
871  p.sort()
872  p = [x[1] for x in p]
873  p = [dct['args'].index(x) for x in p]
874  dct['args_permut'] = perm_inv(p)
875  # order fields
876  f_ordered = [x for x in enumerate(fields)]
877  f_ordered.sort(key=lambda x: (x[1].prio, x[0]))
878  candidates = bases[0].gen_modes(mcs, name, bases, dct, fields)
879  for i, fc in f_ordered:
880  if isinstance(fc, bs_divert):
881  candidates = fc.divert(i, candidates)
882  for cls, name, bases, dct, fields in candidates:
883  ndct = dict(dct)
884  fields = [f for f in fields if f]
885  ndct['fields'] = fields
886  ndct['mn_len'] = sum([x.l for x in fields])
887  c = type.__new__(cls, name, bases, ndct)
888  c.alias = alias
889  c.check_mnemo(fields)
890  c.num = bases[0].num
891  bases[0].num += 1
892  bases[0].all_mn.append(c)
893  mode = dct['mode']
894  bases[0].all_mn_mode[mode].append(c)
895  bases[0].all_mn_name[c.name].append(c)
896  i = c()
897  i.init_class()
898  bases[0].all_mn_inst[c].append(i)
899  add_candidate(bases, c)
900  # gen byte lookup
901  off = 0
902  o = ""
903  for f in i.fields_order:
904  if not isinstance(f, bsi):
905  raise ValueError('f is not bsi')
906  if f.l == 0:
907  continue
908  o += f.strbits
909  return c
910 
911 
913 
914  def __init__(self, name, mode, args, additional_info=None):
915  self.name = name
916  self.mode = mode
917  self.args = args
918  self.additional_info = additional_info
919 
920  def gen_args(self, args):
921  out = ', '.join([str(x) for x in args])
922  return out
923 
924  def __str__(self):
925  o = "%-10s " % self.name
926  args = []
927  for i, arg in enumerate(self.args):
928  if not isinstance(arg, m2_expr.Expr):
929  raise ValueError('zarb arg type')
930  x = self.arg2str(arg, pos = i)
931  args.append(x)
932  o += self.gen_args(args)
933  return o
934 
935  def get_asm_offset(self, expr):
936  return m2_expr.ExprInt_from(expr, self.offset)
937 
938  def resolve_args_with_symbols(self, symbols=None):
939  if symbols is None:
940  symbols = {}
941  args_out = []
942  for a in self.args:
943  e = a
944  # try to resolve symbols using symbols (0 for default value)
945  ids = m2_expr.get_expr_ids(e)
946  fixed_ids = {}
947  for x in ids:
948  if isinstance(x.name, asmbloc.asm_label):
949  name = x.name.name
950  # special symbol $
951  if name == '$':
952  fixed_ids[x] = self.get_asm_offset(x)
953  continue
954  if not name in symbols:
955  raise ValueError('unresolved symbol! %r' % x)
956  else:
957  name = x.name
958  if not name in symbols:
959  continue
960  if symbols[name].offset is None:
961  raise ValueError('The offset of label "%s" cannot be '
962  'determined' % name)
963  else:
964  size = x.size
965  if size is None:
966  default_size = self.get_symbol_size(x, symbols)
967  size = default_size
968  value = m2_expr.ExprInt(symbols[name].offset, size)
969  fixed_ids[x] = value
970  e = e.replace_expr(fixed_ids)
971  e = expr_simp(e)
972  args_out.append(e)
973  return args_out
974 
975  def get_info(self, c):
976  return
977 
978 
979 class cls_mn(object):
980  __metaclass__ = metamn
981  args_symb = []
982  instruction = instruction
983  # Block's offset alignement
984  alignment = 1
985 
986  @classmethod
987  def guess_mnemo(cls, bs, attrib, pre_dis_info, offset):
988  candidates = []
989 
990  candidates = set()
991 
992  fname_values = pre_dis_info
993  todo = [(dict(fname_values), branch, offset * 8)
994  for branch in cls.bintree.items()]
995  cpt = 0
996  if hasattr(bs, 'getlen'):
997  bs_l = bs.getlen()
998  else:
999  bs_l = len(bs)
1000  for fname_values, branch, offset_b in todo:
1001  (l, fmask, fbits, fname, flen), vals = branch
1002  cpt += 1
1003 
1004  if flen is not None:
1005  l = flen(attrib, fname_values)
1006  if l is not None:
1007  try:
1008  v = cls.getbits(bs, attrib, offset_b, l)
1009  except IOError:
1010  # Raised if offset is out of bound
1011  continue
1012  offset_b += l
1013  if v & fmask != fbits:
1014  continue
1015  if fname is not None and not fname in fname_values:
1016  fname_values[fname] = v
1017  for nb, v in vals.items():
1018  if 'mn' in nb:
1019  candidates.update(v)
1020  else:
1021  todo.append((dict(fname_values), (nb, v), offset_b))
1022 
1023  candidates = [c for c in candidates]
1024 
1025  if not candidates:
1026  raise Disasm_Exception('cannot disasm (guess) at %X' % offset)
1027  return candidates
1028 
1029  def reset_class(self):
1030  for f in self.fields_order:
1031  if f.strbits and isbin(f.strbits):
1032  f.value = int(f.strbits, 2)
1033  elif 'default_val' in f.kargs:
1034  f.value = int(f.kargs['default_val'], 2)
1035  else:
1036  f.value = None
1037  if f.fname:
1038  setattr(self, f.fname, f)
1039 
1040  def init_class(self):
1041  args = []
1042  fields_order = []
1043  to_decode = []
1044  off = 0
1045  for i, fc in enumerate(self.fields):
1046  f = fc.gen(self)
1047  f.offset = off
1048  off += f.l
1049  fields_order.append(f)
1050  to_decode.append((i, f))
1051 
1052  if isinstance(f, m_arg):
1053  args.append(f)
1054  if f.fname:
1055  setattr(self, f.fname, f)
1056  if hasattr(self, 'args_permut'):
1057  args = [args[self.args_permut[i]]
1058  for i in xrange(len(self.args_permut))]
1059  to_decode.sort(key=lambda x: (x[1].order, x[0]))
1060  to_decode = [fields_order.index(f[1]) for f in to_decode]
1061  self.args = args
1062  self.fields_order = fields_order
1063  self.to_decode = to_decode
1064 
1065  def add_pre_dis_info(self, prefix=None):
1066  return True
1067 
1068  @classmethod
1069  def getbits(cls, bs, attrib, offset_b, l):
1070  return bs.getbits(offset_b, l)
1071 
1072  @classmethod
1073  def getbytes(cls, bs, offset, l):
1074  return bs.getbytes(offset, l)
1075 
1076  @classmethod
1077  def pre_dis(cls, v_o, attrib, offset):
1078  return {}, v_o, attrib, offset, 0
1079 
1080  def post_dis(self):
1081  return self
1082 
1083  @classmethod
1084  def check_mnemo(cls, fields):
1085  pass
1086 
1087  @classmethod
1088  def mod_fields(cls, fields):
1089  return fields
1090 
1091  @classmethod
1092  def dis(cls, bs_o, mode_o = None, offset=0):
1093  if not isinstance(bs_o, bin_stream):
1094  bs_o = bin_stream_str(bs_o)
1095 
1096  offset_o = offset
1097  pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis(
1098  bs_o, mode_o, offset)
1099  candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset)
1100  out = []
1101  out_c = []
1102  if hasattr(bs, 'getlen'):
1103  bs_l = bs.getlen()
1104  else:
1105  bs_l = len(bs)
1106 
1107  alias = False
1108  for c in candidates:
1109  log.debug("*" * 40, mode, c.mode)
1110  log.debug(c.fields)
1111 
1112  c = cls.all_mn_inst[c][0]
1113 
1114  c.reset_class()
1115  c.mode = mode
1116 
1117  if not c.add_pre_dis_info(pre_dis_info):
1118  continue
1119 
1120  args = []
1121  todo = {}
1122  getok = True
1123  fname_values = dict(pre_dis_info)
1124  offset_b = offset * 8
1125 
1126  total_l = 0
1127  for i, f in enumerate(c.fields_order):
1128  if f.flen is not None:
1129  l = f.flen(mode, fname_values)
1130  else:
1131  l = f.l
1132  if l is not None:
1133  total_l += l
1134  f.l = l
1135  f.is_present = True
1136  log.debug("FIELD %s %s %s %s", f.__class__, f.fname,
1137  offset_b, l)
1138  if bs_l * 8 - offset_b < l:
1139  getok = False
1140  break
1141  bv = cls.getbits(bs, mode, offset_b, l)
1142  offset_b += l
1143  if not f.fname in fname_values:
1144  fname_values[f.fname] = bv
1145  todo[i] = bv
1146  else:
1147  f.is_present = False
1148  todo[i] = None
1149 
1150  if not getok:
1151  continue
1152 
1153  c.l = prefix_len + total_l / 8
1154  for i in c.to_decode:
1155  f = c.fields_order[i]
1156  if f.is_present:
1157  ret = f.decode(todo[i])
1158  if not ret:
1159  log.debug("cannot decode %r", f)
1160  break
1161 
1162  if not ret:
1163  continue
1164  for a in c.args:
1165  a.expr = expr_simp(a.expr)
1166 
1167  c.b = cls.getbytes(bs, offset_o, c.l)
1168  c.offset = offset_o
1169  c = c.post_dis()
1170  if c is None:
1171  continue
1172  c_args = [a.expr for a in c.args]
1173  instr = cls.instruction(c.name, mode, c_args,
1174  additional_info=c.additional_info())
1175  instr.l = prefix_len + total_l / 8
1176  instr.b = cls.getbytes(bs, offset_o, instr.l)
1177  instr.offset = offset_o
1178  instr.get_info(c)
1179  if c.alias:
1180  alias = True
1181  out.append(instr)
1182  out_c.append(c)
1183  if not out:
1184  raise Disasm_Exception('cannot disasm at %X' % offset_o)
1185  if len(out) != 1:
1186  if not alias:
1187  log.warning('dis multiple args ret default')
1188 
1189  assert(len(out) == 2)
1190  for i, o in enumerate(out_c):
1191  if o.alias:
1192  return out[i]
1193  raise NotImplementedError('not fully functional')
1194  return out[0]
1195 
1196  @classmethod
1197  def fromstring(cls, s, mode = None):
1198  global total_scans
1199  name = re.search('(\S+)', s).groups()
1200  if not name:
1201  raise ValueError('cannot find name', s)
1202  name = name[0]
1203 
1204  if not name in cls.all_mn_name:
1205  raise ValueError('unknown name', name)
1206  clist = [x for x in cls.all_mn_name[name]]
1207  out = []
1208  out_args = []
1209  parsers = defaultdict(dict)
1210 
1211  for cc in clist:
1212  for c in cls.get_cls_instance(cc, mode):
1213  args_expr = []
1214  args_str = s[len(name):].strip(' ')
1215 
1216  start = 0
1217  cannot_parse = False
1218  len_o = len(args_str)
1219 
1220  for i, f in enumerate(c.args):
1221  start_i = len_o - len(args_str)
1222  if type(f.parser) == tuple:
1223  parser = f.parser
1224  else:
1225  parser = (f.parser,)
1226  for p in parser:
1227  if p in parsers[(i, start_i)]:
1228  continue
1229  try:
1230  total_scans += 1
1231  v, start, stop = p.scanString(args_str).next()
1232  except StopIteration:
1233  v, start, stop = [None], None, None
1234  if start != 0:
1235  v, start, stop = [None], None, None
1236  parsers[(i, start_i)][p] = v[0], start, stop
1237 
1238  start, stop = f.fromstring(args_str, parsers[(i, start_i)])
1239  if start != 0:
1240  log.debug("cannot fromstring %r", args_str)
1241  cannot_parse = True
1242  break
1243  if f.expr is None:
1244  raise NotImplementedError('not fully functional')
1245  f.expr = expr_simp(f.expr)
1246  args_expr.append(f.expr)
1247  a = args_str[start:stop]
1248  args_str = args_str[stop:].strip(' ')
1249  if args_str.startswith(','):
1250  args_str = args_str[1:]
1251  args_str = args_str.strip(' ')
1252  if args_str:
1253  cannot_parse = True
1254  if cannot_parse:
1255  continue
1256 
1257  out.append(c)
1258  out_args.append(args_expr)
1259  break
1260 
1261  if len(out) == 0:
1262  raise ValueError('cannot fromstring %r' % s)
1263  if len(out) != 1:
1264  log.debug('fromstring multiple args ret default')
1265  c = out[0]
1266  c_args = out_args[0]
1267 
1268  instr = cls.instruction(c.name, mode, c_args,
1269  additional_info=c.additional_info())
1270  return instr
1271 
1272  def dup_info(self, infos):
1273  return
1274 
1275  @classmethod
1276  def get_cls_instance(cls, cc, mode, infos=None):
1277  c = cls.all_mn_inst[cc][0]
1278 
1279  c.reset_class()
1280  c.add_pre_dis_info()
1281  c.dup_info(infos)
1282 
1283  c.mode = mode
1284  yield c
1285 
1286  @classmethod
1287  def asm(cls, instr, symbols=None):
1288  """
1289  Re asm instruction by searching mnemo using name and args. We then
1290  can modify args and get the hex of a modified instruction
1291  """
1292  clist = cls.all_mn_name[instr.name]
1293  clist = [x for x in clist]
1294  vals = []
1295  candidates = []
1296  args = instr.resolve_args_with_symbols(symbols)
1297 
1298  for cc in clist:
1299 
1300  for c in cls.get_cls_instance(
1301  cc, instr.mode, instr.additional_info):
1302 
1303  cannot_parse = False
1304  if len(c.args) != len(instr.args):
1305  continue
1306 
1307  # only fix args expr
1308  for i in xrange(len(c.args)):
1309  c.args[i].expr = args[i]
1310 
1311  v = c.value(instr.mode)
1312  if not v:
1313  log.debug("cannot encode %r", c)
1314  cannot_parse = True
1315  if cannot_parse:
1316  continue
1317  vals += v
1318  candidates.append((c, v))
1319  if len(vals) == 0:
1320  raise ValueError('cannot asm %r %r' %
1321  (instr.name, [str(x) for x in instr.args]))
1322  if len(vals) != 1:
1323  log.debug('asm multiple args ret default')
1324 
1325  vals = cls.filter_asm_candidates(instr, candidates)
1326  return vals
1327 
1328  @classmethod
1329  def filter_asm_candidates(cls, instr, candidates):
1330  o = []
1331  for c, v in candidates:
1332  o += v
1333  o.sort(key=len)
1334  return o
1335 
1336  def value(self, mode):
1337  todo = [(0, 0, [(x, self.fields_order[x]) for x in self.to_decode[::-1]])]
1338 
1339  result = []
1340  done = []
1341  cpt = 0
1342 
1343  while todo:
1344  index, cur_len, to_decode = todo.pop()
1345  # TEST XXX
1346  for i, f in to_decode:
1347  setattr(self, f.fname, f)
1348  if (index, [x[1].value for x in to_decode]) in done:
1349  continue
1350  done.append((index, [x[1].value for x in to_decode]))
1351 
1352  cpt += 1
1353  can_encode = True
1354  for i, f in to_decode[index:]:
1355  f.parent.l = cur_len
1356  ret = f.encode()
1357  if not ret:
1358  log.debug('cannot encode %r', f)
1359  can_encode = False
1360  break
1361  if f.value is not None and f.l:
1362  cur_len += f.l
1363  index += 1
1364  if ret is True:
1365  continue
1366 
1367  gcpt = 0
1368  for i in ret:
1369  gcpt += 1
1370  o = []
1371  if ((index, cur_len, [xx[1].value for xx in to_decode]) in todo or
1372  (index, cur_len, [xx[1].value for xx in to_decode]) in done):
1373  raise NotImplementedError('not fully functional')
1374 
1375  for p, f in to_decode:
1376  fnew = f.clone()
1377  o.append((p, fnew))
1378  todo.append((index, cur_len, o))
1379  can_encode = False
1380 
1381  break
1382  if not can_encode:
1383  continue
1384  result.append(to_decode)
1385 
1386  return self.decoded2bytes(result)
1387 
1388  def encodefields(self, decoded):
1389  bits = bitobj()
1390  for p, f in decoded:
1391  setattr(self, f.fname, f)
1392 
1393  if f.value is None:
1394  continue
1395  bits.putbits(f.value, f.l)
1396 
1397  xx = bits.tostring()
1398  return bits.tostring()
1399 
1400  def decoded2bytes(self, result):
1401  if not result:
1402  return []
1403 
1404  out = []
1405  for decoded in result:
1406  decoded.sort()
1407 
1408  o = self.encodefields(decoded)
1409  if o is None:
1410  continue
1411  out.append(o)
1412  out = list(set(out))
1413  return out
1414 
1415  def gen_args(self, args):
1416  out = ', '.join([str(x) for x in args])
1417  return out
1418 
1419  def args2str(self):
1420  args = []
1421  for arg in self.args:
1422  # XXX todo test
1423  if not (isinstance(arg, m2_expr.Expr) or
1424  isinstance(arg.expr, m2_expr.Expr)):
1425  raise ValueError('zarb arg type')
1426  x = str(arg)
1427  args.append(x)
1428  return args
1429 
1430  def __str__(self):
1431  o = "%-10s " % self.name
1432  args = []
1433  for arg in self.args:
1434  # XXX todo test
1435  if not (isinstance(arg, m2_expr.Expr) or
1436  isinstance(arg.expr, m2_expr.Expr)):
1437  raise ValueError('zarb arg type')
1438  x = str(arg)
1439  args.append(x)
1440 
1441  o += self.gen_args(args)
1442  return o
1443 
1444  def parse_prefix(self, v):
1445  return 0
1446 
1447  def set_dst_symbol(self, symbol_pool):
1448  dst = self.getdstflow(symbol_pool)
1449  args = []
1450  for d in dst:
1451  if isinstance(d, m2_expr.ExprInt):
1452  l = symbol_pool.getby_offset_create(int(d.arg))
1453 
1454  a = m2_expr.ExprId(l.name, d.size)
1455  else:
1456  a = d
1457  args.append(a)
1458  self.args_symb = args
1459 
1460  def getdstflow(self, symbol_pool):
1461  return [self.args[0].expr]
1462 
1463 
1465  intsize = 32
1466  intmask = (1 << intsize) - 1
1467 
1468  def int2expr(self, v):
1469  if (v & ~self.intmask) != 0:
1470  return None
1471  return m2_expr.ExprInt(v, self.intsize)
1472 
1473  def expr2int(self, e):
1474  if not isinstance(e, m2_expr.ExprInt):
1475  return None
1476  v = int(e.arg)
1477  if v & ~self.intmask != 0:
1478  return None
1479  return v
1480 
1481  def fromstring(self, s, parser_result=None):
1482  if parser_result:
1483  e, start, stop = parser_result[self.parser]
1484  else:
1485  try:
1486  e, start, stop = self.parser.scanString(s).next()
1487  except StopIteration:
1488  return None, None
1489  if e is None:
1490  return None, None
1491 
1492  assert(isinstance(e, m2_expr.Expr))
1493  if isinstance(e, tuple):
1494  self.expr = self.int2expr(e[1])
1495  elif isinstance(e, m2_expr.Expr):
1496  self.expr = e
1497  else:
1498  raise TypeError('zarb expr')
1499  if self.expr is None:
1500  log.debug('cannot fromstring int %r', s)
1501  return None, None
1502  return start, stop
1503 
1504  def decodeval(self, v):
1505  return v
1506 
1507  def encodeval(self, v):
1508  if v > self.lmask:
1509  return False
1510  return v
1511 
1512  def decode(self, v):
1513  v = v & self.lmask
1514  v = self.decodeval(v)
1515  e = self.int2expr(v)
1516  if not e:
1517  return False
1518  self.expr = e
1519  return True
1520 
1521  def encode(self):
1522  v = self.expr2int(self.expr)
1523  if v is None:
1524  return False
1525  v = self.encodeval(v)
1526  if v is False:
1527  return False
1528  self.value = v
1529  return True
1530 
1531 
1533  int2expr = lambda self, x: m2_expr.ExprInt08(x)
1534 
1535 
1537  int2expr = lambda self, x: m2_expr.ExprInt16(x)
1538 
1539 
1541  int2expr = lambda self, x: m2_expr.ExprInt32(x)
1542 
1543 
1545  int2expr = lambda self, x: m2_expr.ExprInt64(x)
1546 
1547 
1549  intsize = 32
1550  intmask = (1 << intsize) - 1
1551 
1552  def decode(self, v):
1553  v = sign_ext(v, self.l, self.intsize)
1554  v = self.decodeval(v)
1555  self.expr = self.int2expr(v)
1556  return True
1557 
1558  def encode(self):
1559  if not isinstance(self.expr, m2_expr.ExprInt):
1560  return False
1561  v = int(self.expr.arg)
1562  if sign_ext(v & self.lmask, self.l, self.intsize) != v:
1563  return False
1564  v = self.encodeval(v & self.lmask)
1565  self.value = v & self.lmask
1566  return True
1567 
1568 class bs8(bs):
1569  prio = default_prio
1570 
1571  def __init__(self, v, cls=None, fname=None, **kargs):
1572  super(bs8, self).__init__(int2bin(v, 8), 8,
1573  cls=cls, fname=fname, **kargs)
1574 
1575 
1576 
1577 
1578 def swap_uint(size, i):
1579  if size == 8:
1580  return i & 0xff
1581  elif size == 16:
1582  return struct.unpack('<H', struct.pack('>H', i & 0xffff))[0]
1583  elif size == 32:
1584  return struct.unpack('<I', struct.pack('>I', i & 0xffffffff))[0]
1585  elif size == 64:
1586  return struct.unpack('<Q', struct.pack('>Q', i & 0xffffffffffffffff))[0]
1587  raise ValueError('unknown int len %r' % size)
1588 
1589 
1590 def swap_sint(size, i):
1591  if size == 8:
1592  return i
1593  elif size == 16:
1594  return struct.unpack('<h', struct.pack('>H', i & 0xffff))[0]
1595  elif size == 32:
1596  return struct.unpack('<i', struct.pack('>I', i & 0xffffffff))[0]
1597  elif size == 64:
1598  return struct.unpack('<q', struct.pack('>Q', i & 0xffffffffffffffff))[0]
1599  raise ValueError('unknown int len %r' % size)
1600 
1601 
1602 def sign_ext(v, s_in, s_out):
1603  assert(s_in <= s_out)
1604  v &= (1 << s_in) - 1
1605  sign_in = v & (1 << (s_in - 1))
1606  if not sign_in:
1607  return v
1608  m = (1 << (s_out)) - 1
1609  m ^= (1 << s_in) - 1
1610  v |= m
1611  return v
def ast_get_ids
Definition: cpu.py:223
def check_fbits
Definition: cpu.py:438
def _extract_ast_core
Definition: cpu.py:238
def extract_ast_core
Definition: cpu.py:253
def myror32
Definition: cpu.py:345
def getfieldindexby_name
Definition: cpu.py:846
def branch2nodes
Definition: cpu.py:701
def gen_reg
Definition: cpu.py:105
def ast_id2expr
Definition: cpu.py:197
def gen_base_expr
Definition: cpu.py:309
def swap_uint
Definition: cpu.py:1578
def perm_inv
Definition: cpu.py:684
def add_candidate_to_tree
Definition: cpu.py:820
def gen_bsint
Definition: cpu.py:691
def ast_parse_op
Definition: cpu.py:170
def getfieldby_name
Definition: cpu.py:839
def add_candidate
Definition: cpu.py:835
def swap32
Definition: cpu.py:680
def neg_int
Definition: cpu.py:284
def gen_regs
Definition: cpu.py:135
def factor_tree
Definition: cpu.py:796
def factor_fields_all
Definition: cpu.py:786
def parse_op
Definition: cpu.py:160
def ast_raw2expr
Definition: cpu.py:205
def int2expr
Definition: cpu.py:155
def literal_list
Definition: cpu.py:80
def ast_int2expr
Definition: cpu.py:201
def __getitem__
Definition: cpu.py:404
def myrol32
Definition: cpu.py:349
tuple c
Definition: ir2C.py:23
def int2bin
Definition: cpu.py:340
def factor_one_bit
Definition: cpu.py:712
def factor_fields
Definition: cpu.py:749
dictionary all_new_c
Definition: cpu.py:354
def swap_sint
Definition: cpu.py:1590
def sign_ext
Definition: cpu.py:1602
def filter_asm_candidates
Definition: cpu.py:1329
def parse_id
Definition: cpu.py:165
def graph_tree
Definition: cpu.py:805
def swap16
Definition: cpu.py:676
def isbin
Definition: cpu.py:336