diff options
| -rw-r--r-- | miasm2/core/asmbloc.py | 46 | ||||
| -rw-r--r-- | miasm2/core/parse_asm.py | 4 |
2 files changed, 48 insertions, 2 deletions
diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py index e44f27ed..203a49f0 100644 --- a/miasm2/core/asmbloc.py +++ b/miasm2/core/asmbloc.py @@ -221,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: @@ -435,13 +475,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, diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index 5437ca22..e55a9af8 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -316,5 +316,9 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): i += 1 for block in blocks: + # Fix multiple constraints + block.fix_constraints() + + # Log block asmbloc.log_asmbloc.info(block) return blocks, symbol_pool |