diff options
author | Guillaume Knispel <gknispel@proformatique.com> | 2011-05-12 16:11:49 +0200 |
---|---|---|
committer | Guillaume Knispel <gknispel@proformatique.com> | 2011-05-12 16:11:49 +0200 |
commit | 99551b1b16e3f4458b4137d6735cbc54234f5e6d (patch) | |
tree | 3aa2f0adb0dd9ab24320bfaf21af67578cf8934f /asm2c.py | |
parent | c3c735da0ac001d776a304274d45fedada0bf31a (diff) |
asm2c.py: asm tables -> C tables
Diffstat (limited to 'asm2c.py')
-rwxr-xr-x | asm2c.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/asm2c.py b/asm2c.py new file mode 100755 index 0000000..f3ae2d5 --- /dev/null +++ b/asm2c.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +import sys +import re + +def index_pred(lst, pred): + for i, el in enumerate(lst): + if pred(el): + return i + +def is_ida_addr(s): + return re.match(r'(.*:)?[0-9a-fA-F]+$', s) is not None + +autonames = { + 'db': ["byte", 0, "uint8_t"], + 'dw': ["word", 0, "uint16_t"], + 'dd': ["dword", 0, "uint32_t"], +} + +def asm_int(s): + if s.endswith('h'): + return int(s[:-1], 16) + elif s.endswith('o'): + return int(s[:-1], 8) + else: + return int(s) + +class Symb(object): + def __init__(self, op, name): + self.name = name + self.op = op + self.values = [] + def push(self, line): + orig_line = line + line = re.sub(";.*$", "", line) + op_rol = line.split(None, 1) + if len(op_rol) < 2: + print >> sys.stderr, "WARN dummy op in line: %s" % orig_line + return + op, rol = op_rol + if op != self.op: + raise ValueError("op != self.op (%s != %s)" % (op, self.op)) + elems = [el.strip() for el in rol.split(",")] + for el in elems: + if " " in el: + parts = el.split() + if len(parts) != 2 or not parts[0].isdigit() \ + or not parts[1].startswith("dup(") \ + or not parts[1].endswith(")"): + raise ValueError("bad arg %s for op %s" % (el, op)) + nb = int(parts[0]) + val = asm_int(parts[1][4:-1]) + self.values.extend([val] * nb) + else: + self.values.append(asm_int(el)) + def close(self): + pass + def out_lines(self): + yield "static const %s %s[%d] = {" % (autonames[self.op][2], + self.name, + len(self.values)) + for i, v in enumerate(self.values): + if not i or i % 16: + yield "\t0x%X," % v + else: + yield "\t0x%X,\t\t/* 0x%X %d */" % (v, i, i) + yield "};" + yield "" + +def new_symb(op, name): + if name is None: + auto = autonames[op] + name = auto[0] + '_' + str(auto[1]) + auto[1] += 1 + return Symb(op, name) + +symbols = [] +current_symb = None +# dismiss_first_words = None + +lines = sys.stdin.readlines() +for line in lines: + line = line.strip() + elems = line.split() + pos = index_pred(elems, lambda a: a in autonames) + if pos is None: + print >> sys.stderr, "unrecognize line: %s" % line + continue + op = elems[pos] + named = pos > 0 and not is_ida_addr(elems[pos-1]) + # if dimiss_first_words is None and named: + # dimiss_first_words = pos - 1 + if named: + name = elems[pos-1] + if current_symb: + current_symb.close() + current_symb = new_symb(op, name) + symbols.append(current_symb) + current_symb.push(" ".join(elems[pos:])) + +if current_symb: + current_symb.close() + +for symb in symbols: + for line in symb.out_lines(): + print line |