about summary refs log tree commit diff stats
path: root/miasm2/core/parse_asm.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/core/parse_asm.py')
-rw-r--r--miasm2/core/parse_asm.py105
1 files changed, 41 insertions, 64 deletions
diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py
index df419680..7efa17d0 100644
--- a/miasm2/core/parse_asm.py
+++ b/miasm2/core/parse_asm.py
@@ -1,10 +1,11 @@
 #-*- coding:utf-8 -*-
 import re
 
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import ExprId, ExprInt, ExprOp, ExprLoc, \
+    LocKey
 import miasm2.core.asmblock as asmblock
 from miasm2.core.cpu import instruction, base_expr
-from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp
+from miasm2.core.asm_ast import AstInt, AstId, AstOp
 
 declarator = {'byte': 8,
               'word': 16,
@@ -59,72 +60,47 @@ class DirectiveDontSplit(Directive):
     pass
 
 
-def guess_next_new_label(symbol_pool):
+def guess_next_new_label(loc_db):
     """Generate a new label
-    @symbol_pool: the AsmSymbolPool instance"""
+    @loc_db: the LocationDB instance"""
     i = 0
     gen_name = "loc_%.8X"
     while True:
         name = gen_name % i
-        label = symbol_pool.getby_name(name)
+        label = loc_db.get_name_location(name)
         if label is None:
-            return symbol_pool.add_label(name)
+            return loc_db.add_location(name)
         i += 1
 
 
-def replace_expr_labels(expr, symbol_pool, replace_id):
-    """Create AsmLabel of the expression @expr in the @symbol_pool
-    Update @replace_id"""
-
-    if not (isinstance(expr, m2_expr.ExprId) and
-            isinstance(expr.name, asmblock.AsmLabel)):
-        return expr
-
-    old_lbl = expr.name
-    new_lbl = symbol_pool.getby_name_create(old_lbl.name)
-    replace_id[expr] = m2_expr.ExprId(new_lbl, expr.size)
-    return replace_id[expr]
-
-
-def replace_orphan_labels(instr, symbol_pool):
-    """Link orphan labels used by @instr to the @symbol_pool"""
-
-    for i, arg in enumerate(instr.args):
-        replace_id = {}
-        arg.visit(lambda e: replace_expr_labels(e,
-                                                symbol_pool,
-                                                replace_id))
-        instr.args[i] = instr.args[i].replace_expr(replace_id)
-
-
 STATE_NO_BLOC = 0
 STATE_IN_BLOC = 1
 
 
-def asm_ast_to_expr_with_size(arg, symbol_pool, size):
+def asm_ast_to_expr_with_size(arg, loc_db, size):
     if isinstance(arg, AstId):
-        return m2_expr.ExprId(arg.name, size)
+        return ExprId(arg.name, size)
     if isinstance(arg, AstOp):
-        args = [asm_ast_to_expr_with_size(tmp, symbol_pool, size) for tmp in arg.args]
-        return m2_expr.ExprOp(arg.op, *args)
+        args = [asm_ast_to_expr_with_size(tmp, loc_db, size) for tmp in arg.args]
+        return ExprOp(arg.op, *args)
     if isinstance(arg, AstInt):
-        return m2_expr.ExprInt(arg.value, size)
+        return ExprInt(arg.value, size)
     return None
 
-def parse_txt(mnemo, attrib, txt, symbol_pool=None):
-    """Parse an assembly listing. Returns a couple (blocks, symbol_pool), where
-    blocks is a list of asm_bloc and symbol_pool the associated AsmSymbolPool
+def parse_txt(mnemo, attrib, txt, loc_db=None):
+    """Parse an assembly listing. Returns a couple (asmcfg, loc_db), where
+    asmcfg is an AsmCfg instance and loc_db the associated LocationDB
 
     @mnemo: architecture used
     @attrib: architecture attribute
     @txt: assembly listing
-    @symbol_pool: (optional) the AsmSymbolPool instance used to handle labels
+    @loc_db: (optional) the LocationDB instance used to handle labels
     of the listing
 
     """
 
-    if symbol_pool is None:
-        symbol_pool = asmblock.AsmSymbolPool()
+    if loc_db is None:
+        loc_db = asmblock.LocationDB()
 
     C_NEXT = asmblock.AsmConstraint.c_next
     C_TO = asmblock.AsmConstraint.c_to
@@ -145,7 +121,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
         match_re = LABEL_RE.match(line)
         if match_re:
             label_name = match_re.group(1)
-            label = symbol_pool.getby_name_create(label_name)
+            label = loc_db.get_or_create_name_location(label_name)
             lines.append(label)
             continue
         # directive
@@ -182,7 +158,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 for element in data_raw:
                     element = element.strip()
                     element_parsed = base_expr.parseString(element)[0]
-                    element_expr = asm_ast_to_expr_with_size(element_parsed, symbol_pool, size)
+                    element_expr = asm_ast_to_expr_with_size(element_parsed, loc_db, size)
                     expr_list.append(element_expr)
 
                 raw_data = asmblock.AsmRaw(expr_list)
@@ -214,7 +190,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
         match_re = LABEL_RE.match(line)
         if match_re:
             label_name = match_re.group(1)
-            label = symbol_pool.getby_name_create(label_name)
+            label = loc_db.get_or_create_name_location(label_name)
             lines.append(label)
             continue
 
@@ -222,22 +198,19 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
         if ';' in line:
             line = line[:line.find(';')]
         line = line.strip(' ').strip('\t')
-        instr = mnemo.fromstring(line, symbol_pool, attrib)
-
-        # replace orphan AsmLabel with labels from symbol_pool
-        replace_orphan_labels(instr, symbol_pool)
+        instr = mnemo.fromstring(line, loc_db, attrib)
 
         if instr.dstflow():
-            instr.dstflow2label(symbol_pool)
+            instr.dstflow2label(loc_db)
         lines.append(instr)
 
     asmblock.log_asmblock.info("___pre asm oki___")
-    # make blocks
+    # make asmcfg
 
     cur_block = None
     state = STATE_NO_BLOC
     i = 0
-    blocks = asmblock.AsmCFG()
+    asmcfg = asmblock.AsmCFG(loc_db)
     block_to_nlink = None
     delayslot = 0
     while i < len(lines):
@@ -256,21 +229,24 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 block_to_nlink = None
                 i += 1
                 continue
-            elif not isinstance(line, asmblock.AsmLabel):
+            elif not isinstance(line, LocKey):
                 # First line must be a label. If it's not the case, generate
                 # it.
-                label = guess_next_new_label(symbol_pool)
-                cur_block = asmblock.AsmBlock(label, alignment=mnemo.alignment)
+                loc = guess_next_new_label(loc_db)
+                cur_block = asmblock.AsmBlock(loc, alignment=mnemo.alignment)
             else:
                 cur_block = asmblock.AsmBlock(line, alignment=mnemo.alignment)
                 i += 1
             # Generate the current bloc
-            blocks.add_node(cur_block)
+            asmcfg.add_block(cur_block)
             state = STATE_IN_BLOC
             if block_to_nlink:
                 block_to_nlink.addto(
-                    asmblock.AsmConstraint(cur_block.label,
-                                           C_NEXT))
+                    asmblock.AsmConstraint(
+                        cur_block.loc_key,
+                        C_NEXT
+                    )
+                )
             block_to_nlink = None
             continue
 
@@ -287,10 +263,11 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
             elif isinstance(line, asmblock.AsmRaw):
                 cur_block.addline(line)
                 block_to_nlink = cur_block
-            elif isinstance(line, asmblock.AsmLabel):
+            elif isinstance(line, LocKey):
                 if block_to_nlink:
                     cur_block.addto(
-                        asmblock.AsmConstraint(line, C_NEXT))
+                        asmblock.AsmConstraint(line, C_NEXT)
+                    )
                     block_to_nlink = None
                 state = STATE_NO_BLOC
                 continue
@@ -304,8 +281,8 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 if delayslot:
                     raise RuntimeError("Cannot have breakflow in delayslot")
                 if line.dstflow():
-                    for dst in line.getdstflow(symbol_pool):
-                        if not isinstance(dst, m2_expr.ExprId):
+                    for dst in line.getdstflow(loc_db):
+                        if not isinstance(dst, ExprId):
                             continue
                         if dst in mnemo.regs.all_regs_ids:
                             continue
@@ -319,10 +296,10 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 raise RuntimeError("unknown class %s" % line.__class__)
         i += 1
 
-    for block in blocks:
+    for block in asmcfg.blocks:
         # Fix multiple constraints
         block.fix_constraints()
 
         # Log block
         asmblock.log_asmblock.info(block)
-    return blocks, symbol_pool
+    return asmcfg, loc_db