diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/arch/mips32/arch.py | 4 | ||||
| -rw-r--r-- | miasm2/core/asmbloc.py | 80 | ||||
| -rw-r--r-- | miasm2/core/parse_asm.py | 13 |
3 files changed, 64 insertions, 33 deletions
diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py index a5463b6f..f64e09e5 100644 --- a/miasm2/arch/mips32/arch.py +++ b/miasm2/arch/mips32/arch.py @@ -189,7 +189,7 @@ class instruction_mips32(cpu.instruction): class mn_mips32(cpu.cls_mn): - delayslot = 0 + delayslot = 1 name = "mips32" regs = regs bintree = {} @@ -297,7 +297,7 @@ class mips32_fccreg(mips32_reg): parser = reg_info.parser class mips32_imm(cpu.imm_noarg): - parser = cpu.base_expr + parser = base_expr class mips32_s16imm_noarg(mips32_imm): diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py index fb910b3a..904ccfdc 100644 --- a/miasm2/core/asmbloc.py +++ b/miasm2/core/asmbloc.py @@ -77,7 +77,10 @@ class asm_constraint(object): c_next = "c_next" c_bad = "c_bad" - def __init__(self, label=None, c_t=c_to): + def __init__(self, label, c_t=c_to): + # Sanity check + assert isinstance(label, asm_label) + self.label = label self.c_t = c_t @@ -87,21 +90,21 @@ class asm_constraint(object): class asm_constraint_next(asm_constraint): - def __init__(self, label=None): + def __init__(self, label): super(asm_constraint_next, self).__init__( label, c_t=asm_constraint.c_next) class asm_constraint_to(asm_constraint): - def __init__(self, label=None): + def __init__(self, label): super(asm_constraint_to, self).__init__( label, c_t=asm_constraint.c_to) class asm_constraint_bad(asm_constraint): - def __init__(self, label=None): + def __init__(self, label): super(asm_constraint_bad, self).__init__( label, c_t=asm_constraint.c_bad) @@ -218,6 +221,46 @@ class asm_bloc(object): return x.label return None + @staticmethod + def _filter_constraint(constraints): + """Sort and filter @constraints for asm_bloc.bto + @constraints: non-empty set of asm_constraint instance + + Always the same type -> one of the constraint + c_bad and something -> error + c_next and c_to -> c_next + """ + # Only one constraint + if len(constraints) == 1: + return next(iter(constraints)) + + # Constraint type -> set of corresponding constraint + cbytype = {} + for cons in constraints: + cbytype.setdefault(cons.c_t, set()).add(cons) + + # Only one type -> any constraint is OK + if len(cbytype) == 1: + return next(iter(constraints)) + + # At least one c_bad and one other constraint + if asm_constraint.c_bad in cbytype: + raise RuntimeError("Bad type of constraints for the same destination") + + # At least 2 types, c_bad not in types -> types = {c_next, c_to} + # c_to is included in c_next + return next(iter(cbytype[asm_constraint.c_next])) + + def fix_constraints(self): + """Fix next block constraints""" + # destination -> associated constraints + dests = {} + for constraint in self.bto: + dests.setdefault(constraint.label, set()).add(constraint) + + self.bto = set(self._filter_constraint(constraints) + for constraints in dests.itervalues()) + class asm_symbol_pool: @@ -431,13 +474,15 @@ def dis_bloc(mnemo, pool_bin, cur_bloc, offset, job_done, symbol_pool, for c in cur_bloc.bto: if c.c_t == asm_constraint.c_bad: continue - if isinstance(c.label, asm_label): - offsets_to_dis.add(c.label.offset) + offsets_to_dis.add(c.label.offset) if add_next_offset: cur_bloc.add_cst(offset, asm_constraint.c_next, symbol_pool) offsets_to_dis.add(offset) + # Fix multiple constraints + cur_bloc.fix_constraints() + if dis_bloc_callback is not None: dis_bloc_callback(mn=mnemo, attrib=attrib, pool_bin=pool_bin, cur_bloc=cur_bloc, offsets_to_dis=offsets_to_dis, @@ -455,8 +500,6 @@ def split_bloc(mnemo, attrib, pool_bin, blocs, bloc_dst = [symbol_pool._offset2label[x] for x in more_ref] for b in blocs: for c in b.bto: - if not isinstance(c.label, asm_label): - continue if c.c_t == asm_constraint.c_bad: continue bloc_dst.append(c.label) @@ -479,9 +522,7 @@ def split_bloc(mnemo, attrib, pool_bin, blocs, log_asmbloc.error("cannot split %x!!", off) continue if dis_bloc_callback: - offsets_to_dis = set( - [x.label.offset for x in new_b.bto - if isinstance(x.label, asm_label)]) + offsets_to_dis = set(x.label.offset for x in new_b.bto) dis_bloc_callback(mn=mnemo, attrib=attrib, pool_bin=pool_bin, cur_bloc=new_b, offsets_to_dis=offsets_to_dis, symbol_pool=symbol_pool) @@ -582,15 +623,7 @@ def bloc2graph(blocks, label=False, lines=True): # Generate links for block in blocks: for next_b in block.bto: - if (isinstance(next_b.label, m2_expr.ExprId) or - isinstance(next_b.label, asm_label)): - src, dst, cst = block.label.name, next_b.label.name, next_b.c_t - else: - continue - if isinstance(src, asm_label): - src = src.name - if isinstance(dst, asm_label): - dst = dst.name + src, dst, cst = block.label.name, next_b.label.name, next_b.c_t edge_color = "black" if next_b.c_t == asm_constraint.c_next: @@ -1099,8 +1132,7 @@ class basicblocs: self.blocs[b.label] = b self.g.add_node(b.label) for dst in b.bto: - if isinstance(dst.label, asm_label): - self.g.add_edge(b.label, dst.label) + self.g.add_edge(b.label, dst.label) def add_blocs(self, ab): for b in ab: @@ -1118,7 +1150,7 @@ class basicblocs: def find_parents(blocs, l): p = set() for b in blocs: - if l in [x.label for x in b.bto if isinstance(x.label, asm_label)]: + if l in [x.label for x in b.bto]: p.add(b.label) return p @@ -1266,8 +1298,6 @@ def bloc_merge(blocs, dont_merge=[]): # update parents for s in b.bto: - if not isinstance(s.label, asm_label): - continue if s.label.name == None: continue if not s.label in blocby_label: diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index 646ad445..e55a9af8 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -238,10 +238,9 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): delayslot = 0 while i < len(lines): if delayslot: + delayslot -= 1 if delayslot == 0: state = STATE_NO_BLOC - else: - delayslot -= 1 line = lines[i] # no current block if state == STATE_NO_BLOC: @@ -306,18 +305,20 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): continue if dst in mnemo.regs.all_regs_ids: continue - cur_block.addto(asmbloc.asm_constraint(dst, C_TO)) + cur_block.addto(asmbloc.asm_constraint(dst.name, C_TO)) if not line.splitflow(): block_to_nlink = None - delayslot = line.delayslot - if delayslot == 0: - state = STATE_NO_BLOC + delayslot = line.delayslot + 1 else: raise RuntimeError("unknown class %s" % line.__class__) i += 1 for block in blocks: + # Fix multiple constraints + block.fix_constraints() + + # Log block asmbloc.log_asmbloc.info(block) return blocks, symbol_pool |