diff options
Diffstat (limited to 'miasm2/core/parse_asm.py')
| -rw-r--r-- | miasm2/core/parse_asm.py | 105 |
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 |