summaryrefslogtreecommitdiff
path: root/asm2c.py
diff options
context:
space:
mode:
Diffstat (limited to 'asm2c.py')
-rwxr-xr-xasm2c.py106
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