7 from collections
import defaultdict
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)
30 bits = list(bin(int(str(s).encode(
'hex'), 16))[2:])
31 bits = [int(x)
for x
in bits]
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
46 raise ValueError(
'not enought bits %r %r' % (n, len(self.
bits)))
48 b = int(
"".join([str(x)
for x
in b]), 2)
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
61 if len(self.
bits) % 8:
63 'num bits must be 8 bit aligned: %d' % len(self.
bits))
64 b = int(
"".join([str(x)
for x
in self.
bits]), 2)
66 b =
'0' * (len(self.
bits) / 4 - len(b)) + b
84 o = pyparsing.Literal(l[0])
86 o |= pyparsing.Literal(x)
98 i = self.str.index(s[0])
102 return self.expr.index(e)
107 Gen reg expr and parser
111 reg_pc_expr = [ExprId(x, sz) for x in reg_pc_str]
112 regpc = reg_info(reg_pc_str, reg_pc_expr)
114 class bs_rname(m_reg):
117 bsrname = bs(l=0, cls=(bs_rname,))
120 rnamel = rname.lower()
121 r = m2_expr.ExprId(rname, sz)
126 cname =
"bs_" + rnamel
127 c =
type(cname, (m_reg,), {
'reg': regi})
129 env[
"regi_" + rnamel] = regi
131 env[
"bs" + rnamel] =
bs(l=0, cls=(c,))
140 r = m2_expr.ExprId(rname, sz)
141 r_init = m2_expr.ExprId(rname+
'_init', sz)
142 regs_str.append(rname)
144 regs_init.append(r_init)
147 reginfo =
reg_info(regs_str, regs_expr)
148 return regs_expr, regs_init, reginfo
151 LPARENTHESIS = pyparsing.Literal(
"(")
152 RPARENTHESIS = pyparsing.Literal(
")")
157 return (m2_expr.ExprInt, v)
162 return (m2_expr.ExprOp, v)
167 return (m2_expr.ExprId, v)
174 if t[0]
in [
'-',
'+',
'!']:
175 return m2_expr.ExprOp(t[0], t[1])
182 return m2_expr.ExprOp(t[1], t[0], t[2])
185 o1, op, o2 = t.pop(), t.pop(), t.pop()
190 e = m2_expr.ExprOp(op, o1, o2)
193 raise NotImplementedError(
'strange op')
198 return m2_expr.ExprId(a, 32)
202 return m2_expr.ExprInt32(a)
206 assert(isinstance(a, tuple))
207 if a[0]
is m2_expr.ExprId:
209 elif a[0]
is m2_expr.ExprInt:
210 e = my_int2expr(a[1])
211 elif a[0]
is m2_expr.ExprOp:
214 if isinstance(x, tuple):
219 raise TypeError(
'unknown type')
224 assert(isinstance(a, tuple))
225 if a[0]
is m2_expr.ExprId:
227 elif a[0]
is m2_expr.ExprInt:
229 elif a[0]
is m2_expr.ExprOp:
232 if isinstance(x, tuple):
235 raise TypeError(
'unknown type')
239 assert(isinstance(a, tuple))
240 if a[0]
in [m2_expr.ExprInt, m2_expr.ExprId]:
242 elif a[0]
is m2_expr.ExprOp:
245 if isinstance(x, tuple):
248 return tuple([a[0]] + [out])
250 raise TypeError(
'unknown type')
256 ids_expr = [my_id2expr(x)
for x
in ids]
257 sizes = set([i.size
for i
in ids_expr])
261 elif len(sizes) == 1:
263 my_int2expr =
lambda x: m2_expr.ExprInt(x, size)
265 raise ValueError(
'multiple sizes in ids')
272 def __init__(self, id2expr, int2expr, extract_ast=extract_ast_core):
279 if isinstance(v, m2_expr.Expr):
289 integer = pyparsing.Word(pyparsing.nums).setParseAction(
lambda _a, _b, t:
291 hex_word = pyparsing.Literal(
'0x') + pyparsing.Word(pyparsing.hexnums)
292 hex_int = pyparsing.Combine(hex_word).setParseAction(
lambda _a, _b, t:
296 str_int_pos = (hex_int | integer)
297 str_int_neg = (pyparsing.Suppress(
'-') + \
298 (hex_int | integer)).setParseAction(neg_int)
300 str_int = str_int_pos | str_int_neg
301 str_int.setParseAction(int2expr)
303 logicop = pyparsing.oneOf(
'& | ^ >> << <<< >>>')
304 signop = pyparsing.oneOf(
'+ -')
305 multop = pyparsing.oneOf(
'* / %')
306 plusop = pyparsing.oneOf(
'+ -')
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,
318 (signop, 1, pyparsing.opAssoc.RIGHT,
320 (multop, 2, pyparsing.opAssoc.LEFT,
322 (plusop, 2, pyparsing.opAssoc.LEFT,
325 return variable, operand, base_expr
331 base_expr.setParseAction(my_var_parser)
333 default_prio = 0x1337
337 return re.match(
'[0-1]+$', s)
341 s =
'0' * l + bin(i)[2:]
346 return ((v & 0xFFFFFFFFL) >> r) | ((v << (32 - r)) & 0xFFFFFFFFL)
350 return ((v & 0xFFFFFFFFL) >> (32 - r)) | ((v << r) & 0xFFFFFFFFL)
357 def __init__(self, strbits=None, l=None, cls=None,
358 fname=
None, order=0, flen=
None, **kargs):
360 fname = hex(id(str((strbits, l, cls, fname, order, flen, kargs))))
365 if strbits
and isbin(strbits):
366 value = int(strbits, 2)
367 elif 'default_val' in kargs:
368 value = int(kargs[
'default_val'], 2)
371 allbits = list(strbits)
389 if 'flen' in b.__dict__:
390 flen = getattr(b,
'flen')
405 return getattr(self, item)
408 o = self.__class__.__name__
410 o +=
"_%s" % self.
fname
411 o +=
"_%(strbits)s" % self
413 o +=
'_' +
'_'.join([x.__name__
for x
in self.
cls])
419 c_name +=
'_' +
'_'.join([x.__name__
for x
in self.
cls])
420 bases = list(self.
cls)
426 k = c_name, tuple(bases)
430 new_c =
type(c_name, tuple(bases), {})
443 raise NotImplementedError(
'not fully functional')
460 def __init__(self, parent, strbits, l, cls, fname, order,
461 lmask, fbits, fmask, value, flen, **kargs):
474 self.__dict__.update(self.
kargs)
484 s = self.__class__(self.
parent,
488 s.__dict__.update(self.
kargs)
489 if hasattr(self,
'expr'):
495 for k, v
in self.kargs.items():
496 if isinstance(v, list):
503 return hash(tuple(l))
513 if item
in self.__dict__:
514 return self.__dict__[item]
515 elif item
in self.
args:
516 return self.args.get(item)
526 for candidate
in candidates:
527 cls, name, bases, dct, fields = candidate
528 for new_name, value
in self.
args[
'name'].items():
531 args = dict(self.
args)
532 args.update({
'strbits': s})
536 ndct[
'name'] = new_name
537 out.append((cls, new_name, bases, ndct, nfields))
546 for candidate
in candidates:
547 cls, name, bases, dct, fields = candidate
548 tab = self.
args[
'mn_mod']
549 if isinstance(tab, list):
551 for j, v
in enumerate(tab):
554 for value, new_name
in tab.items():
557 args = dict(self.
args)
558 args.update({
'strbits': s})
562 ndct[
'name'] = self.
modname(ndct[
'name'], value)
563 out.append((cls, new_name, bases, ndct, nfields))
567 return name + self.
args[
'mn_mod'][i]
574 class bs_swapargs(bs_divert):
578 for cls, name, bases, dct, fields
in candidates:
585 out.append((cls, name, bases, ndct, nfields))
590 ap = ndct[
'args_permut'][:]
593 ndct[
'args_permut'] = [b, a] + ap
598 out.append((cls, name, bases, ndct, nfields))
606 e, start, stop = parser_result[self.parser]
610 v, start, stop = self.parser.scanString(s).next()
611 except StopIteration:
622 return self.reg.parser
629 return self.
expr == self.reg.expr[0]
638 e, start, stop = parser_result[self.
parser]
642 v, start, stop = self.parser.scanString(s).next()
643 except StopIteration:
650 if v >= len(self.reg_info.expr):
652 self.
expr = self.reg_info.expr[v]
656 if not self.
expr in self.reg_info.expr:
657 log.debug(
"cannot encode reg %r", self.
expr)
660 if self.
value > self.lmask:
661 log.debug(
"cannot encode field value %x %x",
662 self.
value, self.lmask)
677 return struct.unpack(
'<H', struct.pack(
'>H', v))[0]
681 return struct.unpack(
'<I', struct.pack(
'>I', v))[0]
685 o = [
None for x
in xrange(len(p))]
686 for i, x
in enumerate(p):
694 args.update({
'strbits': s})
704 for k, v
in branch.items():
705 if not isinstance(v, dict):
708 nodes.append((k, k2))
713 if isinstance(tree, set):
715 new_keys = defaultdict(
lambda: defaultdict(dict))
718 for k, v
in tree.items():
722 l, fmask, fbits, fname, flen = k
723 if flen
is not None or l <= 1:
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')
735 for k, v
in new_keys.items():
738 if len(new_keys) != 1:
740 subtree = new_keys.values()[0]
741 if len(subtree) != 1:
743 if subtree.keys()[0] ==
'mn':
750 if not isinstance(tree, dict):
755 k1, v1 = tree.items()[0]
758 l1, fmask1, fbits1, fname1, flen1 = k1
759 if fname1
is not None:
761 if flen1
is not None:
764 if not isinstance(v1, dict):
768 k2, v2 = v1.items()[0]
771 l2, fmask2, fbits2, fname2, flen2 = k2
772 if fname2
is not None:
774 if flen2
is not None:
777 fmask = (fmask1 << l2) | fmask2
778 fbits = (fbits1 << l2) | fbits2
781 k = l, fmask, fbits, fname, flen
787 if not isinstance(tree, dict):
790 for k, v
in tree.items():
799 min_len = min([x[0]
for x
in tree.keys()])
815 out +=
"%s -> %s;\n" % (id(a), id(b))
817 open(
'graph.txt',
'w').write(out)
825 node = f.l, f.fmask, f.fbits, f.fname, f.flen
827 if not node
in branch:
829 branch = branch[node]
830 if not 'mn' in branch:
840 f = filter(
lambda x: hasattr(x,
'fname')
and x.fname == fname, fields)
842 raise ValueError(
'more than one field with name: %s' % fname)
847 for i, f
in enumerate(fields):
848 if hasattr(f,
'fname')
and f.fname == fname:
856 if name ==
"cls_mn" or name.startswith(
'mn_'):
857 return type.__new__(mcs, name, bases, dct)
858 alias = dct.get(
'alias',
False)
860 fields = bases[0].mod_fields(dct[
'fields'])
861 if not 'name' in dct:
862 dct[
"name"] = bases[0].getmn(name)
867 for i, a
in enumerate(dct[
'args']):
870 p.append((fields.index(a), a))
872 p = [x[1]
for x
in p]
873 p = [dct[
'args'].index(x)
for x
in p]
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:
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)
889 c.check_mnemo(fields)
892 bases[0].all_mn.append(c)
894 bases[0].all_mn_mode[mode].append(c)
895 bases[0].all_mn_name[c.name].append(c)
898 bases[0].all_mn_inst[c].append(i)
903 for f
in i.fields_order:
904 if not isinstance(f, bsi):
905 raise ValueError(
'f is not bsi')
914 def __init__(self, name, mode, args, additional_info=None):
921 out =
', '.join([str(x)
for x
in args])
925 o =
"%-10s " % self.
name
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)
936 return m2_expr.ExprInt_from(expr, self.offset)
945 ids = m2_expr.get_expr_ids(e)
954 if not name
in symbols:
955 raise ValueError(
'unresolved symbol! %r' % x)
958 if not name
in symbols:
960 if symbols[name].offset
is None:
961 raise ValueError(
'The offset of label "%s" cannot be '
966 default_size = self.get_symbol_size(x, symbols)
968 value = m2_expr.ExprInt(symbols[name].offset, size)
970 e = e.replace_expr(fixed_ids)
980 __metaclass__ = metamn
982 instruction = instruction
992 fname_values = pre_dis_info
993 todo = [(dict(fname_values), branch, offset * 8)
994 for branch
in cls.bintree.items()]
996 if hasattr(bs,
'getlen'):
1000 for fname_values, branch, offset_b
in todo:
1001 (l, fmask, fbits, fname, flen), vals = branch
1004 if flen
is not None:
1005 l = flen(attrib, fname_values)
1008 v = cls.getbits(bs, attrib, offset_b, l)
1013 if v & fmask != fbits:
1015 if fname
is not None and not fname
in fname_values:
1016 fname_values[fname] = v
1017 for nb, v
in vals.items():
1019 candidates.update(v)
1021 todo.append((dict(fname_values), (nb, v), offset_b))
1023 candidates = [c
for c
in candidates]
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)
1038 setattr(self, f.fname, f)
1045 for i, fc
in enumerate(self.fields):
1049 fields_order.append(f)
1050 to_decode.append((i, f))
1052 if isinstance(f, m_arg):
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]
1070 return bs.getbits(offset_b, l)
1074 return bs.getbytes(offset, l)
1078 return {}, v_o, attrib, offset, 0
1092 def dis(cls, bs_o, mode_o = None, offset=0):
1093 if not isinstance(bs_o, bin_stream):
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)
1102 if hasattr(bs,
'getlen'):
1108 for c
in candidates:
1109 log.debug(
"*" * 40, mode, c.mode)
1112 c = cls.all_mn_inst[c][0]
1117 if not c.add_pre_dis_info(pre_dis_info):
1123 fname_values = dict(pre_dis_info)
1124 offset_b = offset * 8
1127 for i, f
in enumerate(c.fields_order):
1128 if f.flen
is not None:
1129 l = f.flen(mode, fname_values)
1136 log.debug(
"FIELD %s %s %s %s", f.__class__, f.fname,
1138 if bs_l * 8 - offset_b < l:
1141 bv = cls.getbits(bs, mode, offset_b, l)
1143 if not f.fname
in fname_values:
1144 fname_values[f.fname] = bv
1147 f.is_present =
False
1153 c.l = prefix_len + total_l / 8
1154 for i
in c.to_decode:
1155 f = c.fields_order[i]
1157 ret = f.decode(todo[i])
1159 log.debug(
"cannot decode %r", f)
1167 c.b = cls.getbytes(bs, offset_o, c.l)
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
1187 log.warning(
'dis multiple args ret default')
1189 assert(len(out) == 2)
1190 for i, o
in enumerate(out_c):
1193 raise NotImplementedError(
'not fully functional')
1199 name = re.search(
'(\S+)', s).groups()
1201 raise ValueError(
'cannot find name', s)
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]]
1209 parsers = defaultdict(dict)
1212 for c
in cls.get_cls_instance(cc, mode):
1214 args_str = s[len(name):].strip(
' ')
1217 cannot_parse =
False
1218 len_o = len(args_str)
1220 for i, f
in enumerate(c.args):
1221 start_i = len_o - len(args_str)
1222 if type(f.parser) == tuple:
1225 parser = (f.parser,)
1227 if p
in parsers[(i, start_i)]:
1231 v, start, stop = p.scanString(args_str).next()
1232 except StopIteration:
1233 v, start, stop = [
None],
None,
None
1235 v, start, stop = [
None],
None,
None
1236 parsers[(i, start_i)][p] = v[0], start, stop
1238 start, stop = f.fromstring(args_str, parsers[(i, start_i)])
1240 log.debug(
"cannot fromstring %r", args_str)
1244 raise NotImplementedError(
'not fully functional')
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(
' ')
1258 out_args.append(args_expr)
1262 raise ValueError(
'cannot fromstring %r' % s)
1264 log.debug(
'fromstring multiple args ret default')
1266 c_args = out_args[0]
1268 instr = cls.instruction(c.name, mode, c_args,
1269 additional_info=c.additional_info())
1277 c = cls.all_mn_inst[cc][0]
1280 c.add_pre_dis_info()
1287 def asm(cls, instr, symbols=None):
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
1292 clist = cls.all_mn_name[instr.name]
1293 clist = [x
for x
in clist]
1296 args = instr.resolve_args_with_symbols(symbols)
1300 for c
in cls.get_cls_instance(
1301 cc, instr.mode, instr.additional_info):
1303 cannot_parse =
False
1304 if len(c.args) != len(instr.args):
1308 for i
in xrange(len(c.args)):
1309 c.args[i].expr = args[i]
1311 v = c.value(instr.mode)
1313 log.debug(
"cannot encode %r", c)
1318 candidates.append((c, v))
1320 raise ValueError(
'cannot asm %r %r' %
1321 (instr.name, [str(x)
for x
in instr.args]))
1323 log.debug(
'asm multiple args ret default')
1325 vals = cls.filter_asm_candidates(instr, candidates)
1331 for c, v
in candidates:
1344 index, cur_len, to_decode = todo.pop()
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:
1350 done.append((index, [x[1].value
for x
in to_decode]))
1354 for i, f
in to_decode[index:]:
1355 f.parent.l = cur_len
1358 log.debug(
'cannot encode %r', f)
1361 if f.value
is not None and f.l:
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')
1375 for p, f
in to_decode:
1378 todo.append((index, cur_len, o))
1384 result.append(to_decode)
1390 for p, f
in decoded:
1391 setattr(self, f.fname, f)
1395 bits.putbits(f.value, f.l)
1397 xx = bits.tostring()
1398 return bits.tostring()
1405 for decoded
in result:
1412 out = list(set(out))
1416 out =
', '.join([str(x)
for x
in args])
1421 for arg
in self.
args:
1423 if not (isinstance(arg, m2_expr.Expr)
or
1424 isinstance(arg.expr, m2_expr.Expr)):
1425 raise ValueError(
'zarb arg type')
1431 o =
"%-10s " % self.name
1433 for arg
in self.
args:
1435 if not (isinstance(arg, m2_expr.Expr)
or
1436 isinstance(arg.expr, m2_expr.Expr)):
1437 raise ValueError(
'zarb arg type')
1451 if isinstance(d, m2_expr.ExprInt):
1452 l = symbol_pool.getby_offset_create(int(d.arg))
1454 a = m2_expr.ExprId(l.name, d.size)
1461 return [self.
args[0].expr]
1466 intmask = (1 << intsize) - 1
1471 return m2_expr.ExprInt(v, self.
intsize)
1474 if not isinstance(e, m2_expr.ExprInt):
1483 e, start, stop = parser_result[self.parser]
1486 e, start, stop = self.parser.scanString(s).next()
1487 except StopIteration:
1492 assert(isinstance(e, m2_expr.Expr))
1493 if isinstance(e, tuple):
1495 elif isinstance(e, m2_expr.Expr):
1498 raise TypeError(
'zarb expr')
1499 if self.
expr is None:
1500 log.debug(
'cannot fromstring int %r', s)
1533 int2expr =
lambda self, x: m2_expr.ExprInt08(x)
1537 int2expr =
lambda self, x: m2_expr.ExprInt16(x)
1541 int2expr =
lambda self, x: m2_expr.ExprInt32(x)
1545 int2expr =
lambda self, x: m2_expr.ExprInt64(x)
1550 intmask = (1 << intsize) - 1
1559 if not isinstance(self.
expr, m2_expr.ExprInt):
1561 v = int(self.expr.arg)
1573 cls=cls, fname=fname, **kargs)
1582 return struct.unpack(
'<H', struct.pack(
'>H', i & 0xffff))[0]
1584 return struct.unpack(
'<I', struct.pack(
'>I', i & 0xffffffff))[0]
1586 return struct.unpack(
'<Q', struct.pack(
'>Q', i & 0xffffffffffffffff))[0]
1587 raise ValueError(
'unknown int len %r' % size)
1594 return struct.unpack(
'<h', struct.pack(
'>H', i & 0xffff))[0]
1596 return struct.unpack(
'<i', struct.pack(
'>I', i & 0xffffffff))[0]
1598 return struct.unpack(
'<q', struct.pack(
'>Q', i & 0xffffffffffffffff))[0]
1599 raise ValueError(
'unknown int len %r' % size)
1603 assert(s_in <= s_out)
1604 v &= (1 << s_in) - 1
1605 sign_in = v & (1 << (s_in - 1))
1608 m = (1 << (s_out)) - 1
1609 m ^= (1 << s_in) - 1
def add_candidate_to_tree
def resolve_args_with_symbols
def filter_asm_candidates