diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2018-05-18 14:43:57 +0200 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2018-06-09 00:33:48 +0200 |
| commit | 61551fa78e9dd22ed1f982b4fe171fd6383c39a6 (patch) | |
| tree | b10543391f9a66ddd5e3f6852c30d96b169b623d | |
| parent | a2637cdf0b40df074865d23a7fd71f082ad7f40a (diff) | |
| download | focaccia-miasm-61551fa78e9dd22ed1f982b4fe171fd6383c39a6.tar.gz focaccia-miasm-61551fa78e9dd22ed1f982b4fe171fd6383c39a6.zip | |
Core: replace AsmLabel by LocKey
72 files changed, 1983 insertions, 1798 deletions
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py index 0c08a8a3..0ee32146 100755 --- a/example/asm/shellcode.py +++ b/example/asm/shellcode.py @@ -67,7 +67,7 @@ with open(args.source) as fstream: symbol_pool = asmblock.AsmSymbolPool() -blocks, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source, symbol_pool) +asmcfg, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source, symbol_pool) # Fix shellcode addrs symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main) @@ -77,19 +77,21 @@ if args.PE: pe.DirImport.get_funcvirt('USER32.dll', 'MessageBoxA')) # Print and graph firsts blocks before patching it -for block in blocks: +for block in asmcfg.blocks: print block -open("graph.dot", "w").write(blocks.dot()) +open("graph.dot", "w").write(asmcfg.dot()) # Apply patches patches = asmblock.asm_resolve_final(machine.mn, - blocks, + asmcfg, symbol_pool, dst_interval) if args.encrypt: # Encrypt code - ad_start = symbol_pool.getby_name_create(args.encrypt[0]).offset - ad_stop = symbol_pool.getby_name_create(args.encrypt[1]).offset + loc_start = symbol_pool.getby_name_create(args.encrypt[0]) + loc_stop = symbol_pool.getby_name_create(args.encrypt[1]) + ad_start = symbol_pool.loc_key_to_offset(loc_start) + ad_stop = symbol_pool.loc_key_to_offset(loc_stop) new_patches = dict(patches) for ad, val in patches.items(): diff --git a/example/asm/simple.py b/example/asm/simple.py index 62d2ff80..09df8d94 100644 --- a/example/asm/simple.py +++ b/example/asm/simple.py @@ -6,7 +6,7 @@ from miasm2.core import parse_asm, asmblock # Assemble code -blocks, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' +asmcfg, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' main: MOV EAX, 1 MOV EBX, 2 @@ -21,14 +21,14 @@ loop: RET ''') -# Set 'main' label's offset +# Set 'main' loc_key's offset symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0) # Spread information and resolve instructions offset -patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool) +patches = asmblock.asm_resolve_final(mn_x86, asmcfg, symbol_pool) -# Show resolved blocks -for block in blocks: +# Show resolved asmcfg +for block in asmcfg.blocks: print block # Print offset -> bytes diff --git a/example/disasm/callback.py b/example/disasm/callback.py index 6b7b2b81..bbf0afaf 100644 --- a/example/disasm/callback.py +++ b/example/disasm/callback.py @@ -1,5 +1,5 @@ from miasm2.core.bin_stream import bin_stream_str -from miasm2.core.asmblock import AsmLabel, AsmConstraint +from miasm2.core.asmblock import AsmConstraint from miasm2.arch.x86.disasm import dis_x86_32, cb_x86_funcs @@ -21,14 +21,15 @@ def cb_x86_callpop(cur_bloc, symbol_pool, *args, **kwargs): last_instr = cur_bloc.lines[-1] if last_instr.name != 'CALL': return - ## The destination must be a label + ## The destination must be a location dst = last_instr.args[0] - if not dst.is_label(): + if not dst.is_loc(): return - label = symbol_pool.loc_key_to_label(dst.loc_key) + loc_key = dst.loc_key + offset = symbol_pool.loc_key_to_offset(loc_key) ## The destination must be the next instruction - if label.offset != last_instr.offset + last_instr.l: + if offset != last_instr.offset + last_instr.l: return # Update instruction instance @@ -36,7 +37,7 @@ def cb_x86_callpop(cur_bloc, symbol_pool, *args, **kwargs): # Update next blocks to process in the disassembly engine cur_bloc.bto.clear() - cur_bloc.add_cst(label.offset, AsmConstraint.c_next, symbol_pool) + cur_bloc.add_cst(loc_key, AsmConstraint.c_next, symbol_pool) # Prepare a tiny shellcode @@ -48,8 +49,8 @@ bin_stream = bin_stream_str(shellcode) mdis = dis_x86_32(bin_stream) print "Without callback:\n" -blocks = mdis.dis_multiblock(0) -print "\n".join(str(block) for block in blocks) +asmcfg = mdis.dis_multiblock(0) +print "\n".join(str(block) for block in asmcfg.blocks) # Enable callback cb_x86_funcs.append(cb_x86_callpop) @@ -58,9 +59,9 @@ cb_x86_funcs.append(cb_x86_callpop) print "=" * 40 print "With callback:\n" -blocks_after = mdis.dis_multiblock(0) -print "\n".join(str(block) for block in blocks_after) +asmcfg_after = mdis.dis_multiblock(0) +print "\n".join(str(block) for block in asmcfg_after.blocks) # Ensure the callback has been called -assert blocks.heads()[0].lines[0].name == "CALL" -assert blocks_after.heads()[0].lines[0].name == "PUSH" +assert asmcfg.loc_key_to_block(asmcfg.heads()[0]).lines[0].name == "CALL" +assert asmcfg_after.loc_key_to_block(asmcfg_after.heads()[0]).lines[0].name == "PUSH" diff --git a/example/disasm/full.py b/example/disasm/full.py index e693a687..b0c34bff 100644 --- a/example/disasm/full.py +++ b/example/disasm/full.py @@ -3,7 +3,7 @@ from argparse import ArgumentParser from pdb import pm from miasm2.analysis.binary import Container -from miasm2.core.asmblock import log_asmblock, AsmLabel, AsmCFG +from miasm2.core.asmblock import log_asmblock, AsmCFG from miasm2.expression.expression import ExprId from miasm2.core.interval import interval from miasm2.analysis.machine import Machine @@ -99,7 +99,9 @@ for addr in args.address: addrs.append(int(addr, 0)) except ValueError: # Second chance, try with symbol - addrs.append(mdis.symbol_pool.getby_name(addr).offset) + loc_key = mdis.symbol_pool.getby_name(addr) + offset = mdis.symbol_pool.loc_key_to_offset(loc_key) + addrs.append(offset) if len(addrs) == 0 and default_addr is not None: addrs.append(default_addr) @@ -121,27 +123,28 @@ while not finish and todo: if ad in done: continue done.add(ad) - allblocks = mdis.dis_multiblock(ad) + asmcfg = mdis.dis_multiblock(ad) log.info('func ok %.16x (%d)' % (ad, len(all_funcs))) all_funcs.add(ad) - all_funcs_blocks[ad] = allblocks - for block in allblocks: + all_funcs_blocks[ad] = asmcfg + for block in asmcfg.blocks: for l in block.lines: done_interval += interval([(l.offset, l.offset + l.l)]) if args.funcswatchdog is not None: args.funcswatchdog -= 1 if args.recurfunctions: - for block in allblocks: + for block in asmcfg.blocks: instr = block.get_subcall_instr() if not instr: continue for dest in instr.getdstflow(mdis.symbol_pool): - if not (isinstance(dest, ExprId) and isinstance(dest.name, AsmLabel)): + if not dest.is_loc(): continue - todo.append((mdis, instr, dest.name.offset)) + offset = mdis.symbol_pool.loc_key_to_offset(dest.loc_key) + todo.append((mdis, instr, offset)) if args.funcswatchdog is not None and args.funcswatchdog <= 0: finish = True @@ -155,13 +158,13 @@ while not finish and todo: # Generate dotty graph -all_blocks = AsmCFG(mdis.symbol_pool) +all_asmcfg = AsmCFG(mdis.symbol_pool) for blocks in all_funcs_blocks.values(): - all_blocks += blocks + all_asmcfg += blocks log.info('generate graph file') -open('graph_execflow.dot', 'w').write(all_blocks.dot(offset=True)) +open('graph_execflow.dot', 'w').write(all_asmcfg.dot(offset=True)) log.info('generate intervals') @@ -190,9 +193,9 @@ if args.gen_ir: ir_arch_a = ira(mdis.symbol_pool) ir_arch.blocks = {} ir_arch_a.blocks = {} - for ad, all_block in all_funcs_blocks.items(): + for ad, asmcfg in all_funcs_blocks.items(): log.info("generating IR... %x" % ad) - for block in all_block: + for block in asmcfg.blocks: ir_arch_a.add_block(block) ir_arch.add_block(block) diff --git a/example/disasm/function.py b/example/disasm/function.py index 89f65abb..10495dbc 100644 --- a/example/disasm/function.py +++ b/example/disasm/function.py @@ -8,9 +8,9 @@ from miasm2.arch.x86.disasm import dis_x86_32 # RET shellcode = '\xb8\xef\xbe7\x13\xb9\x04\x00\x00\x00\xc1\xc0\x08\xe2\xfb\xc3' mdis = dis_x86_32(shellcode) -blocks = mdis.dis_multiblock(0) +asmcfg = mdis.dis_multiblock(0) -for block in blocks: +for block in asmcfg.blocks: print block -open('graph.dot', 'w').write(blocks.dot()) +open('graph.dot', 'w').write(asmcfg.dot()) diff --git a/example/expression/access_c.py b/example/expression/access_c.py index de158730..8856f6f8 100644 --- a/example/expression/access_c.py +++ b/example/expression/access_c.py @@ -100,7 +100,7 @@ def get_funcs_arg0(ctx, ira, lbl_head): for irb, index in find_call(ira): instr = irb[index].instr print 'Analysing references from:', hex(instr.offset), instr - g_list = g_dep.get(irb.label, set([element]), index, set([lbl_head])) + g_list = g_dep.get(irb.loc_key, set([element]), index, set([lbl_head])) for dep in g_list: emul_result = dep.emul(ctx) value = emul_result[element] @@ -143,11 +143,11 @@ dis_engine, ira = machine.dis_engine, machine.ira mdis = dis_engine(cont.bin_stream, symbol_pool=cont.symbol_pool) addr_head = 0 -blocks = mdis.dis_multiblock(addr_head) +asmcfg = mdis.dis_multiblock(addr_head) lbl_head = mdis.symbol_pool.getby_offset(addr_head) ir_arch_a = ira(mdis.symbol_pool) -for block in blocks: +for block in asmcfg.blocks: ir_arch_a.add_block(block) open('graph_irflow.dot', 'w').write(ir_arch_a.graph.dot()) diff --git a/example/expression/asm_to_ir.py b/example/expression/asm_to_ir.py index 786b860e..36965bfa 100644 --- a/example/expression/asm_to_ir.py +++ b/example/expression/asm_to_ir.py @@ -8,7 +8,7 @@ from miasm2.arch.x86.ira import ir_a_x86_32 from miasm2.analysis.data_flow import dead_simp # First, asm code -blocks, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' +asmcfg, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' main: MOV EAX, 1 MOV EBX, 2 @@ -25,17 +25,17 @@ loop: symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0) -for block in blocks: +for block in asmcfg.blocks: print block print "symbols:" print symbol_pool -patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool) +patches = asmblock.asm_resolve_final(mn_x86, asmcfg, symbol_pool) # Translate to IR ir_arch = ir_a_x86_32(symbol_pool) -for block in blocks: +for block in asmcfg.blocks: print 'add block' print block ir_arch.add_block(block) diff --git a/example/expression/constant_propagation.py b/example/expression/constant_propagation.py index 70394580..3a81d909 100644 --- a/example/expression/constant_propagation.py +++ b/example/expression/constant_propagation.py @@ -32,8 +32,8 @@ ir_arch = ira(mdis.symbol_pool) addr = int(args.address, 0) -blocks = mdis.dis_multiblock(addr) -for block in blocks: +asmcfg = mdis.dis_multiblock(addr) +for block in asmcfg.blocks: ir_arch.add_block(block) diff --git a/example/expression/graph_dataflow.py b/example/expression/graph_dataflow.py index dd7e37a1..9b45a52d 100644 --- a/example/expression/graph_dataflow.py +++ b/example/expression/graph_dataflow.py @@ -47,7 +47,7 @@ def intra_block_flow_symb(ir_arch, flow_graph, irblock, in_nodes, out_nodes): all_mems.update(get_expr_mem(n)) for n in all_mems: - node_n_w = get_node_name(irblock.label, 0, n) + node_n_w = get_node_name(irblock.loc_key, 0, n) if not n == src: continue o_r = n.arg.get_r(mem_read=False, cst_read=True) @@ -55,7 +55,7 @@ def intra_block_flow_symb(ir_arch, flow_graph, irblock, in_nodes, out_nodes): if n_r in current_nodes: node_n_r = current_nodes[n_r] else: - node_n_r = get_node_name(irblock.label, i, n_r) + node_n_r = get_node_name(irblock.loc_key, i, n_r) if not n_r in in_nodes: in_nodes[n_r] = node_n_r flow_graph.add_uniq_edge(node_n_r, node_n_w) @@ -69,13 +69,13 @@ def intra_block_flow_symb(ir_arch, flow_graph, irblock, in_nodes, out_nodes): if n_r in current_nodes: node_n_r = current_nodes[n_r] else: - node_n_r = get_node_name(irblock.label, 0, n_r) + node_n_r = get_node_name(irblock.loc_key, 0, n_r) if not n_r in in_nodes: in_nodes[n_r] = node_n_r flow_graph.add_node(node_n_r) for n_w in nodes_w: - node_n_w = get_node_name(irblock.label, 1, n_w) + node_n_w = get_node_name(irblock.loc_key, 1, n_w) out_nodes[n_w] = node_n_w flow_graph.add_node(node_n_w) @@ -96,8 +96,9 @@ def gen_block_data_flow_graph(ir_arch, ad, block_flow_cb): irblock_0 = None for irblock in ir_arch.blocks.values(): - label = ir_arch.symbol_pool.loc_key_to_label(irblock.label) - if label.offset == ad: + loc_key = irblock.loc_key + offset = ir_arch.symbol_pool.loc_key_to_offset(loc_key) + if offset == ad: irblock_0 = irblock break assert(irblock_0 is not None) @@ -120,7 +121,7 @@ def gen_block_data_flow_graph(ir_arch, ad, block_flow_cb): print 'OUT', [str(x) for x in irb_out_nodes[label]] print '*' * 20, 'interblock', '*' * 20 - inter_block_flow(ir_arch, flow_graph, irblock_0.label, irb_in_nodes, irb_out_nodes) + inter_block_flow(ir_arch, flow_graph, irblock_0.loc_key, irb_in_nodes, irb_out_nodes) # from graph_qt import graph_qt # graph_qt(flow_graph) @@ -133,15 +134,14 @@ ad = int(args.addr, 16) print 'disasm...' mdis = dis_x86_32(data) mdis.follow_call = True -ab = mdis.dis_multiblock(ad) +asmcfg = mdis.dis_multiblock(ad) print 'ok' print 'generating dataflow graph for:' ir_arch = ir_a_x86_32(mdis.symbol_pool) -blocks = ab -for block in blocks: +for block in asmcfg.blocks: print block ir_arch.add_block(block) for irblock in ir_arch.blocks.values(): diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py index 76dff96c..42e6670c 100644 --- a/example/expression/solve_condition_stp.py +++ b/example/expression/solve_condition_stp.py @@ -54,8 +54,8 @@ def emul_symb(ir_arch, mdis, states_todo, states_done): cond_group_b = {addr.cond: ExprInt(1, addr.cond.size)} addr_a = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_a), {})) addr_b = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_b), {})) - if not (addr_a.is_int() or addr_a.is_label() and - addr_b.is_int() or addr_b.is_label()): + if not (addr_a.is_int() or addr_a.is_loc() and + addr_b.is_int() or addr_b.is_loc()): print str(addr_a), str(addr_b) raise ValueError("Unsupported condition") if isinstance(addr_a, ExprInt): @@ -70,8 +70,7 @@ def emul_symb(ir_arch, mdis, states_todo, states_done): elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) - elif addr.is_label(): - addr = ir_arch.symbol_pool.loc_key_to_label(addr.loc_key) + elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination") @@ -93,7 +92,7 @@ if __name__ == '__main__': symbexec = SymbolicExecutionEngine(ir_arch, symbols_init) - blocks, symbol_pool = parse_asm.parse_txt(machine.mn, 32, ''' + asmcfg, symbol_pool = parse_asm.parse_txt(machine.mn, 32, ''' init: PUSH argv PUSH argc @@ -107,16 +106,16 @@ if __name__ == '__main__': ret_addr_lbl = symbol_pool.getby_name('ret_addr') init_lbl = symbol_pool.getby_name('init') - argc = ExprLoc(argc_lbl.loc_key, 32) - argv = ExprLoc(argv_lbl.loc_key, 32) - ret_addr = ExprLoc(ret_addr_lbl.loc_key, 32) + argc = ExprLoc(argc_lbl, 32) + argv = ExprLoc(argv_lbl, 32) + ret_addr = ExprLoc(ret_addr_lbl, 32) - block = list(blocks)[0] + block = asmcfg.loc_key_to_block(init_lbl) print block # add fake address and len to parsed instructions ir_arch.add_block(block) - irb = ir_arch.blocks[init_lbl.loc_key] + irb = ir_arch.blocks[init_lbl] symbexec.eval_updt_irblock(irb) symbexec.dump(ids=False) # reset ir_arch blocks diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py index 9b9c2e95..f459022e 100644 --- a/example/ida/ctype_propagation.py +++ b/example/ida/ctype_propagation.py @@ -201,7 +201,7 @@ class SymbExecCTypeFix(SymbExecCType): if expr.is_int(): continue for c_str, c_type in self.chandler.expr_to_c_and_types(expr, self.symbols): - expr = self.cst_propag_link.get((irb.label, index), {}).get(expr, expr) + expr = self.cst_propag_link.get((irb.loc_key, index), {}).get(expr, expr) offset2cmt.setdefault(instr.offset, set()).add( "\n%s: %s\n%s" % (expr, c_str, c_type)) diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py index 5342313a..ece02ad4 100644 --- a/example/ida/depgraph.py +++ b/example/ida/depgraph.py @@ -28,7 +28,8 @@ class depGraphSettingsForm(ida_kernwin.Form): self.address = idc.ScreenEA() cur_block = None for block in ira.getby_offset(self.address): - if block.label.offset is not None: + offset = self.ira.symbol_pool.loc_key_to_offset(block.loc_key) + if offset is not None: # Only one block non-generated assert cur_block is None cur_block = block @@ -38,7 +39,7 @@ class depGraphSettingsForm(ida_kernwin.Form): if assignblk.instr.offset == self.address: break assert line_nb is not None - cur_label = str(cur_block.label) + cur_label = str(cur_block.loc_key) labels = sorted(map(str, ira.blocks.keys())) regs = sorted(ira.arch.regs.all_regs_ids_byname.keys()) regs += self.stk_args.keys() @@ -110,13 +111,13 @@ Method to use: elif mode == 1: return value + 1 else: - return len(self.ira.blocks[self.label]) + return len(self.ira.blocks[self.loc_key]) @property def elements(self): value = self.cbReg.value if value in self.stk_args: - line = self.ira.blocks[self.label][self.line_nb].instr + line = self.ira.blocks[self.loc_key][self.line_nb].instr arg_num = self.stk_args[value] stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size) stk_off = m2_expr.ExprInt(self.ira.sp.size/8 * arg_num, ir_arch.sp.size) @@ -174,7 +175,7 @@ def treat_element(): for node in graph.relevant_nodes: try: - offset = ir_arch.blocks[node.label][node.line_nb].instr.offset + offset = ir_arch.blocks[node.loc_key][node.line_nb].instr.offset except IndexError: print "Unable to highlight %s" % node continue @@ -209,26 +210,27 @@ def launch_depgraph(): for ad, name in idautils.Names(): if name is None: continue - mdis.symbol_pool.add_label(name, ad) + mdis.symbol_pool.add_location(name, ad) # Get the current function addr = idc.ScreenEA() func = ida_funcs.get_func(addr) - blocks = mdis.dis_multiblock(func.startEA) + asmcfg = mdis.dis_multiblock(func.startEA) # Generate IR - for block in blocks: + for block in asmcfg.blocks: ir_arch.add_block(block) # Get settings settings = depGraphSettingsForm(ir_arch) settings.Execute() - label, elements, line_nb = settings.label, settings.elements, settings.line_nb + label, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb # Simplify affectations for irb in ir_arch.blocks.values(): irs = [] - fix_stack = irb.label.offset is not None and settings.unalias_stack + offset = ir_arch.symbol_pool.loc_key_to_offset(irb.loc_key) + fix_stack = offset is not None and settings.unalias_stack for assignblk in irb: if fix_stack: stk_high = m2_expr.ExprInt(idc.GetSpd(assignblk.instr.offset), ir_arch.sp.size) @@ -243,7 +245,7 @@ def launch_depgraph(): dst, src = expr_simp(dst), expr_simp(src) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) - ir_arch.blocks[irb.label] = IRBlock(irb.label, irs) + ir_arch.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) # Get dependency graphs dg = settings.depgraph diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py index fad793ff..370500e5 100644 --- a/example/ida/graph_ir.py +++ b/example/ida/graph_ir.py @@ -6,7 +6,7 @@ import idc import idautils from miasm2.core.bin_stream_ida import bin_stream_ida -from miasm2.core.asmblock import AsmLabel, is_int +from miasm2.core.asmblock import is_int from miasm2.expression.simplifications import expr_simp from miasm2.analysis.data_flow import dead_simp from miasm2.ir.ir import AssignBlock, IRBlock @@ -33,17 +33,15 @@ def label_str(self): else: return "%s:%s" % (self.name, str(self.offset)) -AsmLabel.__init__ = label_init -AsmLabel.__str__ = label_str def color_irblock(irblock, ir_arch): out = [] - lbl = idaapi.COLSTR(str(irblock.label), idaapi.SCOLOR_INSN) + lbl = idaapi.COLSTR(ir_arch.symbol_pool.str_loc_key(irblock.loc_key), idaapi.SCOLOR_INSN) out.append(lbl) for assignblk in irblock: for dst, src in sorted(assignblk.iteritems()): - dst_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, dst) - src_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, src) + dst_f = expr2colorstr(dst, symbol_pool=ir_arch.symbol_pool) + src_f = expr2colorstr(src, symbol_pool=ir_arch.symbol_pool) line = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN) out.append(' %s' % line) out.append("") @@ -74,7 +72,7 @@ class GraphMiasmIR(idaapi.GraphViewer): continue all_dst = self.ir_arch.dst_trackback(irblock) for dst in all_dst: - if not dst.is_label(): + if not dst.is_loc(): continue if not dst.loc_key in self.ir_arch.blocks: continue @@ -123,7 +121,7 @@ def build_graph(verbose=False, simplify=False): mdis.symbol_pool.getby_name(name)): # Symbol alias continue - mdis.symbol_pool.add_label(name, addr) + mdis.symbol_pool.add_location(name, addr) if verbose: print "start disasm" @@ -131,15 +129,15 @@ def build_graph(verbose=False, simplify=False): if verbose: print hex(addr) - blocks = mdis.dis_multiblock(addr) + asmcfg = mdis.dis_multiblock(addr) if verbose: print "generating graph" - open('asm_flow.dot', 'w').write(blocks.dot()) + open('asm_flow.dot', 'w').write(asmcfg.dot()) print "generating IR... %x" % addr - for block in blocks: + for block in asmcfg.blocks: if verbose: print 'ADD' print block @@ -156,7 +154,7 @@ def build_graph(verbose=False, simplify=False): for dst, src in assignblk.iteritems() } irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) - ir_arch.blocks[irb.label] = IRBlock(irb.label, irs) + ir_arch.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs) if verbose: out = ir_arch.graph.dot() diff --git a/example/ida/symbol_exec.py b/example/ida/symbol_exec.py index f019f77d..63014ece 100644 --- a/example/ida/symbol_exec.py +++ b/example/ida/symbol_exec.py @@ -34,8 +34,16 @@ class ActionHandlerTranslate(ActionHandler): class symbolicexec_t(idaapi.simplecustviewer_t): def add(self, key, value): - self.AddLine("%s = %s" % (expr2colorstr(self.machine.mn.regs.all_regs_ids, key), - expr2colorstr(self.machine.mn.regs.all_regs_ids, value))) + self.AddLine("%s = %s" % ( + expr2colorstr( + key, + symbol_pool=self.symbol_pool + ), + expr2colorstr( + value, + symbol_pool=self.symbol_pool + ) + )) def expand(self, linenum): element = self.line2eq[linenum] @@ -61,11 +69,12 @@ class symbolicexec_t(idaapi.simplecustviewer_t): form.Compile() form.Execute() - def Create(self, equations, machine, *args, **kwargs): + def Create(self, equations, machine, symbol_pool, *args, **kwargs): if not super(symbolicexec_t, self).Create(*args, **kwargs): return False self.machine = machine + self.symbol_pool = symbol_pool self.line2eq = sorted(equations.items(), key=operator.itemgetter(0)) self.lines_expanded = set() @@ -126,9 +135,9 @@ def symbolic_exec(): start, end = idc.SelStart(), idc.SelEnd() mdis.dont_dis = [end] - blocks = mdis.dis_multiblock(start) - ira = machine.ira() - for block in blocks: + asmcfg = mdis.dis_multiblock(start) + ira = machine.ira(symbol_pool=mdis.symbol_pool) + for block in asmcfg.blocks: ira.add_block(block) print "Run symbolic execution..." @@ -141,7 +150,7 @@ def symbolic_exec(): view = symbolicexec_t() all_views.append(view) - if not view.Create(modified, machine, + if not view.Create(modified, machine, mdis.symbol_pool, "Symbolic Execution - 0x%x to 0x%x" % (start, end)): return diff --git a/example/ida/utils.py b/example/ida/utils.py index e026f2fc..481220a9 100644 --- a/example/ida/utils.py +++ b/example/ida/utils.py @@ -72,22 +72,29 @@ class TranslatorIDA(Translator): # Implemented language __LANG__ = "ida_w_color" - def __init__(self, regs_ids=None, **kwargs): + def __init__(self, symbol_pool=None, **kwargs): super(TranslatorIDA, self).__init__(**kwargs) - if regs_ids is None: - regs_ids = {} - self.regs_ids = regs_ids + self.symbol_pool = symbol_pool def str_protected_child(self, child, parent): - return ("(%s)" % self.from_expr(child)) if m2_expr.should_parenthesize_child(child, parent) else self.from_expr(child) + return ("(%s)" % ( + self.from_expr(child)) if m2_expr.should_parenthesize_child(child, parent) + else self.from_expr(child) + ) def from_ExprInt(self, expr): return idaapi.COLSTR(str(expr), idaapi.SCOLOR_NUMBER) def from_ExprId(self, expr): - out = str(expr) - if expr in self.regs_ids: - out = idaapi.COLSTR(out, idaapi.SCOLOR_REG) + out = idaapi.COLSTR(str(expr), idaapi.SCOLOR_REG) + return out + + def from_ExprLoc(self, expr): + if self.symbol_pool is not None: + out = self.symbol_pool.str_loc_key(expr.loc_key) + else: + out = str(expr) + out = idaapi.COLSTR(out, idaapi.SCOLOR_REG) return out def from_ExprMem(self, expr): @@ -126,20 +133,23 @@ class TranslatorIDA(Translator): return (' ' + expr._op + ' ').join([self.str_protected_child(arg, expr) for arg in expr._args]) return (expr._op + '(' + - ', '.join([self.from_expr(arg) for arg in expr._args]) + ')') + ', '.join( + self.from_expr(arg) + for arg in expr._args + ) + ')') def from_ExprAff(self, expr): return "%s = %s" % tuple(map(expr.from_expr, (expr.dst, expr.src))) -def expr2colorstr(regs_ids, expr): +def expr2colorstr(expr, symbol_pool): """Colorize an Expr instance for IDA - @regs_ids: list of ExprId corresponding to available registers @expr: Expr instance to colorize + @symbol_pool: AsmSymbolPool instance """ - translator = TranslatorIDA(regs_ids) + translator = TranslatorIDA(symbol_pool=symbol_pool) return translator.from_expr(expr) diff --git a/example/jitter/sandbox_call.py b/example/jitter/sandbox_call.py index dc64af15..7a9fd946 100644 --- a/example/jitter/sandbox_call.py +++ b/example/jitter/sandbox_call.py @@ -15,7 +15,8 @@ sb = Sandbox_Linux_arml(options.filename, options, globals()) with open(options.filename, "rb") as fdesc: cont = Container.from_stream(fdesc) - addr_to_call = cont.symbol_pool.getby_name("md5_starts").offset + loc_key = cont.symbol_pool.getby_name("md5_starts") + addr_to_call = cont.symbol_pool.loc_key_to_offset(loc_key) # Calling md5_starts(malloc(0x64)) addr = linobjs.heap.alloc(sb.jitter, 0x64) diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py index f9b0aed1..b86724d6 100644 --- a/example/jitter/unpack_upx.py +++ b/example/jitter/unpack_upx.py @@ -59,10 +59,11 @@ leaves = list(ab.get_bad_blocks_predecessors()) assert(len(leaves) == 1) l = leaves.pop() logging.info(l) -end_label = l.label.offset -logging.info('final label') -logging.info(end_label) +end_loc_key = mdis.symbol_pool.loc_key_to_offset(l) + +logging.info('final loc_key') +logging.info(end_loc_key) # Export CFG graph (dot format) if options.graph is True: @@ -85,7 +86,7 @@ def update_binary(jitter): return False # Set callbacks -sb.jitter.add_breakpoint(end_label, update_binary) +sb.jitter.add_breakpoint(end_loc_key, update_binary) # Run sb.run() diff --git a/example/symbol_exec/depgraph.py b/example/symbol_exec/depgraph.py index b8d838ae..621e8fca 100644 --- a/example/symbol_exec/depgraph.py +++ b/example/symbol_exec/depgraph.py @@ -59,10 +59,10 @@ if args.rename_args: init_ctx[e_mem] = ExprId("arg%d" % i, 32) # Disassemble the targeted function -blocks = mdis.dis_multiblock(int(args.func_addr, 0)) +asmcfg = mdis.dis_multiblock(int(args.func_addr, 0)) # Generate IR -for block in blocks: +for block in asmcfg.blocks: ir_arch.add_block(block) # Get the instance @@ -81,7 +81,7 @@ for assignblk_index, assignblk in enumerate(current_block): # Enumerate solutions json_solutions = [] -for sol_nb, sol in enumerate(dg.get(current_block.label, elements, assignblk_index, set())): +for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_index, set())): fname = "sol_%d.dot" % sol_nb with open(fname, "w") as fdesc: fdesc.write(sol.graph.dot()) diff --git a/miasm2/analysis/binary.py b/miasm2/analysis/binary.py index 6073e126..f5a727d7 100644 --- a/miasm2/analysis/binary.py +++ b/miasm2/analysis/binary.py @@ -203,7 +203,7 @@ class ContainerELF(Container): if offset == 0: continue try: - self._symbol_pool.add_label(name, offset) + self._symbol_pool.add_location(name, offset) except ValueError: # Two symbols points on the same offset log.warning("Same offset (%s) for %s and %s", diff --git a/miasm2/analysis/cst_propag.py b/miasm2/analysis/cst_propag.py index 18829627..4b5d7834 100644 --- a/miasm2/analysis/cst_propag.py +++ b/miasm2/analysis/cst_propag.py @@ -31,7 +31,7 @@ def add_state(ir_arch, todo, states, addr, state): @addr: address of the concidered block @state: computed state """ - addr = ir_arch.get_label(addr) + addr = ir_arch.get_loc_key(addr) todo.add(addr) if addr not in states: states[addr] = state @@ -108,11 +108,11 @@ class SymbExecStateFix(SymbolicExecutionEngine): for arg in assignblk.instr.args: new_arg = self.propag_expr_cst(arg) links[new_arg] = arg - self.cst_propag_link[(irb.label, index)] = links + self.cst_propag_link[(irb.loc_key, index)] = links self.eval_updt_assignblk(assignblk) assignblks.append(AssignBlock(new_assignblk, assignblk.instr)) - self.ir_arch.blocks[irb.label] = IRBlock(irb.label, assignblks) + self.ir_arch.blocks[irb.loc_key] = IRBlock(irb.loc_key, assignblks) def compute_cst_propagation_states(ir_arch, init_addr, init_infos): @@ -128,7 +128,7 @@ def compute_cst_propagation_states(ir_arch, init_addr, init_infos): done = set() state = SymbExecState.StateEngine(init_infos) - lbl = ir_arch.get_label(init_addr) + lbl = ir_arch.get_loc_key(init_addr) todo = set([lbl]) states = {lbl: state} @@ -153,7 +153,7 @@ def compute_cst_propagation_states(ir_arch, init_addr, init_infos): LOG_CST_PROPAG.warning('Bad destination: %s', value) continue elif value.is_int(): - value = ir_arch.get_label(value) + value = ir_arch.get_loc_key(value) add_state(ir_arch, todo, states, value, symbexec_engine.get_state()) diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py index bceb0bd8..5e88665e 100644 --- a/miasm2/analysis/data_analysis.py +++ b/miasm2/analysis/data_analysis.py @@ -27,7 +27,7 @@ def intra_block_flow_raw(ir_arch, flow_graph, irb, in_nodes, out_nodes): continue for n in all_mems: - node_n_w = get_node_name(irb.label, i, n) + node_n_w = get_node_name(irb.loc_key, i, n) if not n in nodes_r: continue o_r = n.arg.get_r(mem_read=False, cst_read=True) @@ -35,7 +35,7 @@ def intra_block_flow_raw(ir_arch, flow_graph, irb, in_nodes, out_nodes): if n_r in current_nodes: node_n_r = current_nodes[n_r] else: - node_n_r = get_node_name(irb.label, i, n_r) + node_n_r = get_node_name(irb.loc_key, i, n_r) current_nodes[n_r] = node_n_r in_nodes[n_r] = node_n_r flow_graph.add_uniq_edge(node_n_r, node_n_w) @@ -46,13 +46,13 @@ def intra_block_flow_raw(ir_arch, flow_graph, irb, in_nodes, out_nodes): if n_r in current_nodes: node_n_r = current_nodes[n_r] else: - node_n_r = get_node_name(irb.label, i, n_r) + node_n_r = get_node_name(irb.loc_key, i, n_r) current_nodes[n_r] = node_n_r in_nodes[n_r] = node_n_r flow_graph.add_node(node_n_r) - node_n_w = get_node_name(irb.label, i + 1, node_w) + node_n_w = get_node_name(irb.loc_key, i + 1, node_w) out_nodes[node_w] = node_n_w flow_graph.add_node(node_n_w) @@ -81,13 +81,13 @@ def intra_block_flow_symbexec(ir_arch, flow_graph, irb, in_nodes, out_nodes): continue read_values = v.get_r(cst_read=True) # print n_w, v, [str(x) for x in read_values] - node_n_w = get_node_name(irb.label, len(irb), n_w) + node_n_w = get_node_name(irb.loc_key, len(irb), n_w) for n_r in read_values: if n_r in current_nodes: node_n_r = current_nodes[n_r] else: - node_n_r = get_node_name(irb.label, 0, n_r) + node_n_r = get_node_name(irb.loc_key, 0, n_r) current_nodes[n_r] = node_n_r in_nodes[n_r] = node_n_r @@ -109,7 +109,7 @@ def inter_block_flow_link(ir_arch, flow_graph, irb_in_nodes, irb_out_nodes, todo irb = ir_arch.blocks[lbl] # pp(('IN', lbl, [(str(x[0]), str(x[1])) for x in current_nodes.items()])) to_del = set() - for n_r, node_n_r in irb_in_nodes[irb.label].items(): + for n_r, node_n_r in irb_in_nodes[irb.loc_key].items(): if not n_r in current_nodes: continue # print 'add link', current_nodes[n_r], node_n_r @@ -119,7 +119,7 @@ def inter_block_flow_link(ir_arch, flow_graph, irb_in_nodes, irb_out_nodes, todo # if link exec to data, all nodes depends on exec nodes if link_exec_to_data: for n_x_r in exec_nodes: - for n_r, node_n_r in irb_in_nodes[irb.label].items(): + for n_r, node_n_r in irb_in_nodes[irb.loc_key].items(): if not n_x_r in current_nodes: continue if isinstance(n_r, ExprInt): @@ -127,14 +127,14 @@ def inter_block_flow_link(ir_arch, flow_graph, irb_in_nodes, irb_out_nodes, todo flow_graph.add_uniq_edge(current_nodes[n_x_r], node_n_r) # update current nodes using bloc out_nodes - for n_w, node_n_w in irb_out_nodes[irb.label].items(): + for n_w, node_n_w in irb_out_nodes[irb.loc_key].items(): current_nodes[n_w] = node_n_w # get nodes involved in exec flow x_nodes = tuple(sorted(list(irb.dst.get_r()))) todo = set() - for lbl_dst in ir_arch.graph.successors(irb.label): + for lbl_dst in ir_arch.graph.successors(irb.loc_key): todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes)) # pp(('OUT', lbl, [(str(x[0]), str(x[1])) for x in current_nodes.items()])) @@ -150,13 +150,13 @@ def create_implicit_flow(ir_arch, flow_graph, irb_in_nodes, irb_out_ndes): while todo: lbl = todo.pop() irb = ir_arch.blocks[lbl] - for lbl_son in ir_arch.graph.successors(irb.label): + for lbl_son in ir_arch.graph.successors(irb.loc_key): if not lbl_son in ir_arch.blocks: print "cannot find bloc!!", lbl continue irb_son = ir_arch.blocks[lbl_son] - for n_r in irb_in_nodes[irb_son.label]: - if n_r in irb_out_nodes[irb.label]: + for n_r in irb_in_nodes[irb_son.loc_key]: + if n_r in irb_out_nodes[irb.loc_key]: continue if not isinstance(n_r, ExprId): continue @@ -167,13 +167,13 @@ def create_implicit_flow(ir_arch, flow_graph, irb_in_nodes, irb_out_ndes): # print "###", irb_son # print "###", 'IN', [str(x) for x in irb_son.in_nodes] - node_n_w = irb.label, len(irb), n_r - irb_out_nodes[irb.label][n_r] = node_n_w - if not n_r in irb_in_nodes[irb.label]: - irb_in_nodes[irb.label][n_r] = irb.label, 0, n_r - node_n_r = irb_in_nodes[irb.label][n_r] + node_n_w = irb.loc_key, len(irb), n_r + irb_out_nodes[irb.loc_key][n_r] = node_n_w + if not n_r in irb_in_nodes[irb.loc_key]: + irb_in_nodes[irb.loc_key][n_r] = irb.loc_key, 0, n_r + node_n_r = irb_in_nodes[irb.loc_key][n_r] # print "###", node_n_r - for lbl_p in ir_arch.graph.predecessors(irb.label): + for lbl_p in ir_arch.graph.predecessors(irb.loc_key): todo.add(lbl_p) flow_graph.add_uniq_edge(node_n_r, node_n_w) diff --git a/miasm2/analysis/data_flow.py b/miasm2/analysis/data_flow.py index d9f61c56..e780f70c 100644 --- a/miasm2/analysis/data_flow.py +++ b/miasm2/analysis/data_flow.py @@ -57,15 +57,15 @@ class ReachingDefinitions(dict): the assignblk in block @block. """ predecessor_state = {} - for pred_lbl in self.ir_a.graph.predecessors(block.label): + for pred_lbl in self.ir_a.graph.predecessors(block.loc_key): pred = self.ir_a.blocks[pred_lbl] for lval, definitions in self.get_definitions(pred_lbl, len(pred)).iteritems(): predecessor_state.setdefault(lval, set()).update(definitions) - modified = self.get((block.label, 0)) != predecessor_state + modified = self.get((block.loc_key, 0)) != predecessor_state if not modified: return False - self[(block.label, 0)] = predecessor_state + self[(block.loc_key, 0)] = predecessor_state for index in xrange(len(block)): modified |= self.process_assignblock(block, index) @@ -80,13 +80,13 @@ class ReachingDefinitions(dict): """ assignblk = block[assignblk_index] - defs = self.get_definitions(block.label, assignblk_index).copy() + defs = self.get_definitions(block.loc_key, assignblk_index).copy() for lval in assignblk: - defs.update({lval: set([(block.label, assignblk_index)])}) + defs.update({lval: set([(block.loc_key, assignblk_index)])}) - modified = self.get((block.label, assignblk_index + 1)) != defs + modified = self.get((block.loc_key, assignblk_index + 1)) != defs if modified: - self[(block.label, assignblk_index + 1)] = defs + self[(block.loc_key, assignblk_index + 1)] = defs return modified @@ -149,9 +149,9 @@ class DiGraphDefUse(DiGraph): def _compute_def_use_block(self, block, reaching_defs, deref_mem=False): for index, assignblk in enumerate(block): - assignblk_reaching_defs = reaching_defs.get_definitions(block.label, index) + assignblk_reaching_defs = reaching_defs.get_definitions(block.loc_key, index) for lval, expr in assignblk.iteritems(): - self.add_node(AssignblkNode(block.label, index, lval)) + self.add_node(AssignblkNode(block.loc_key, index, lval)) read_vars = expr.get_r(mem_read=deref_mem) if deref_mem and lval.is_mem(): @@ -159,7 +159,7 @@ class DiGraphDefUse(DiGraph): for read_var in read_vars: for reach in assignblk_reaching_defs.get(read_var, set()): self.add_data_edge(AssignblkNode(reach[0], reach[1], read_var), - AssignblkNode(block.label, index, lval)) + AssignblkNode(block.loc_key, index, lval)) def del_edge(self, src, dst): super(DiGraphDefUse, self).del_edge(src, dst) @@ -257,9 +257,9 @@ def dead_simp(ir_a): for idx, assignblk in enumerate(block): new_assignblk = dict(assignblk) for lval in assignblk: - if AssignblkNode(block.label, idx, lval) not in useful: + if AssignblkNode(block.loc_key, idx, lval) not in useful: del new_assignblk[lval] modified = True irs.append(AssignBlock(new_assignblk, assignblk.instr)) - ir_a.blocks[block.label] = IRBlock(block.label, irs) + ir_a.blocks[block.loc_key] = IRBlock(block.loc_key, irs) return modified diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py index 49368508..0f4d168d 100644 --- a/miasm2/analysis/depgraph.py +++ b/miasm2/analysis/depgraph.py @@ -2,6 +2,7 @@ from miasm2.expression.expression import ExprInt, ExprLoc, ExprAff from miasm2.core.graph import DiGraph +from miasm2.core.asmblock import AsmSymbolPool from miasm2.expression.simplifications import expr_simp from miasm2.ir.symbexec import SymbolicExecutionEngine from miasm2.ir.ir import IRBlock, AssignBlock @@ -19,23 +20,23 @@ class DependencyNode(object): """Node elements of a DependencyGraph A dependency node stands for the dependency on the @element at line number - @line_nb in the IRblock named @label, *before* the evaluation of this + @line_nb in the IRblock named @loc_key, *before* the evaluation of this line. """ - __slots__ = ["_label", "_element", "_line_nb", "_hash"] + __slots__ = ["_loc_key", "_element", "_line_nb", "_hash"] - def __init__(self, label, element, line_nb): + def __init__(self, loc_key, element, line_nb): """Create a dependency node with: - @label: AsmLabel instance + @loc_key: LocKey instance @element: Expr instance @line_nb: int """ - self._label = label + self._loc_key = loc_key self._element = element self._line_nb = line_nb self._hash = hash( - (self._label, self._element, self._line_nb)) + (self._loc_key, self._element, self._line_nb)) def __hash__(self): """Returns a hash of @self to uniquely identify @self""" @@ -45,7 +46,7 @@ class DependencyNode(object): """Returns True if @self and @depnode are equals.""" if not isinstance(depnode, self.__class__): return False - return (self.label == depnode.label and + return (self.loc_key == depnode.loc_key and self.element == depnode.element and self.line_nb == depnode.line_nb) @@ -54,13 +55,13 @@ class DependencyNode(object): if not isinstance(node, self.__class__): return cmp(self.__class__, node.__class__) - return cmp((self.label, self.element, self.line_nb), - (node.label, node.element, node.line_nb)) + return cmp((self.loc_key, self.element, self.line_nb), + (node.loc_key, node.element, node.line_nb)) def __str__(self): """Returns a string representation of DependencyNode""" return "<%s %s %s %s>" % (self.__class__.__name__, - self.label, self.element, + self.loc_key, self.element, self.line_nb) def __repr__(self): @@ -68,9 +69,9 @@ class DependencyNode(object): return self.__str__() @property - def label(self): + def loc_key(self): "Name of the current IRBlock" - return self._label + return self._loc_key @property def element(self): @@ -89,9 +90,9 @@ class DependencyState(object): Store intermediate depnodes states during dependencygraph analysis """ - def __init__(self, label, pending, line_nb=None): - self.label = label - self.history = [label] + def __init__(self, loc_key, pending, line_nb=None): + self.loc_key = loc_key + self.history = [loc_key] self.pending = {k: set(v) for k, v in pending.iteritems()} self.line_nb = line_nb self.links = set() @@ -100,22 +101,22 @@ class DependencyState(object): self._graph = None def __repr__(self): - return "<State: %r (%r) (%r)>" % (self.label, + return "<State: %r (%r) (%r)>" % (self.loc_key, self.pending, self.links) - def extend(self, label): + def extend(self, loc_key): """Return a copy of itself, with itself in history - @label: AsmLabel instance for the new DependencyState's label + @loc_key: LocKey instance for the new DependencyState's loc_key """ - new_state = self.__class__(label, self.pending) + new_state = self.__class__(loc_key, self.pending) new_state.links = set(self.links) - new_state.history = self.history + [label] + new_state.history = self.history + [loc_key] return new_state def get_done_state(self): """Returns immutable object representing current state""" - return (self.label, frozenset(self.links)) + return (self.loc_key, frozenset(self.links)) def as_graph(self): """Generates a Digraph of dependencies""" @@ -156,7 +157,7 @@ class DependencyState(object): @line_nb: the element's line """ - depnode = DependencyNode(self.label, element, line_nb) + depnode = DependencyNode(self.loc_key, element, line_nb) if not self.pending[element]: # Create start node self.links.add((depnode, None)) @@ -174,14 +175,14 @@ class DependencyState(object): @future_pending: the future dependencies """ - depnode = DependencyNode(self.label, element, line_nb) + depnode = DependencyNode(self.loc_key, element, line_nb) # Update pending, add link to unfollowed nodes for dependency in dependencies: if not dependency.follow: # Add non followed dependencies to the dependency graph parent = DependencyNode( - self.label, dependency.element, line_nb) + self.loc_key, dependency.element, line_nb) self.links.add((parent, depnode)) continue # Create future pending between new dependency and the current @@ -195,7 +196,7 @@ class DependencyResult(DependencyState): def __init__(self, ira, initial_state, state, inputs): self.initial_state = initial_state - self.label = state.label + self.loc_key = state.loc_key self.history = state.history self.pending = state.pending self.line_nb = state.line_nb @@ -224,17 +225,17 @@ class DependencyResult(DependencyState): return output @property - def relevant_labels(self): - """List of labels containing nodes influencing inputs. + def relevant_loc_keys(self): + """List of loc_keys containing nodes influencing inputs. The history order is preserved.""" - # Get used labels - used_labels = set(depnode.label for depnode in self.relevant_nodes) + # Get used loc_keys + used_loc_keys = set(depnode.loc_key for depnode in self.relevant_nodes) # Keep history order output = [] - for label in self.history: - if label in used_labels: - output.append(label) + for loc_key in self.history: + if loc_key in used_loc_keys: + output.append(loc_key) return output @@ -254,7 +255,7 @@ class DependencyResult(DependencyState): assignblks = [] line2elements = {} for depnode in self.relevant_nodes: - if depnode.label != irb.label: + if depnode.loc_key != irb.loc_key: continue line2elements.setdefault(depnode.line_nb, set()).add(depnode.element) @@ -265,11 +266,11 @@ class DependencyResult(DependencyState): assignmnts = {} for element in elements: if element in irb[line_nb]: - # constants, label, ... are not in destination + # constants, loc_key, ... are not in destination assignmnts[element] = irb[line_nb][element] assignblks.append(AssignBlock(assignmnts)) - return IRBlock(irb.label, assignblks) + return IRBlock(irb.loc_key, assignblks) def emul(self, ctx=None, step=False): """Symbolic execution of relevant nodes according to the history @@ -286,20 +287,20 @@ class DependencyResult(DependencyState): assignblks = [] # Build a single affectation block according to history - last_index = len(self.relevant_labels) - for index, label in enumerate(reversed(self.relevant_labels), 1): - if index == last_index and label == self.initial_state.label: + last_index = len(self.relevant_loc_keys) + for index, loc_key in enumerate(reversed(self.relevant_loc_keys), 1): + if index == last_index and loc_key == self.initial_state.loc_key: line_nb = self.initial_state.line_nb else: line_nb = None - assignblks += self.irblock_slice(self._ira.blocks[label], + assignblks += self.irblock_slice(self._ira.blocks[loc_key], line_nb).assignblks # Eval the block symbol_pool = AsmSymbolPool() - temp_label = symbol_pool.getby_name_create("Temp") + temp_loc = symbol_pool.getby_name_create("Temp") symb_exec = SymbolicExecutionEngine(self._ira, ctx_init) - symb_exec.eval_updt_irblock(IRBlock(temp_label.loc_key, assignblks), step=step) + symb_exec.eval_updt_irblock(IRBlock(temp_loc, assignblks), step=step) # Return only inputs values (others could be wrongs) return {element: symb_exec.symbols[element] @@ -318,16 +319,16 @@ class DependencyResultImplicit(DependencyResult): def _gen_path_constraints(self, translator, expr, expected): """Generate path constraint from @expr. Handle special case with - generated labels + generated loc_keys """ out = [] expected = self._ira.symbol_pool.canonize_to_exprloc(expected) - expected_is_label = expected.is_label() + expected_is_loc_key = expected.is_loc() for consval in possible_values(expr): value = self._ira.symbol_pool.canonize_to_exprloc(consval.value) - if expected_is_label and value != expected: + if expected_is_loc_key and value != expected: continue - if not expected_is_label and value.is_label(): + if not expected_is_loc_key and value.is_loc_key(): continue conds = z3.And(*[translator.from_expr(cond.to_constraint()) @@ -361,20 +362,20 @@ class DependencyResultImplicit(DependencyResult): translator = Translator.to_language("z3") size = self._ira.IRDst.size - for hist_nb, label in enumerate(history, 1): - if hist_nb == history_size and label == self.initial_state.label: + for hist_nb, loc_key in enumerate(history, 1): + if hist_nb == history_size and loc_key == self.initial_state.loc_key: line_nb = self.initial_state.line_nb else: line_nb = None - irb = self.irblock_slice(self._ira.blocks[label], line_nb) + irb = self.irblock_slice(self._ira.blocks[loc_key], line_nb) # Emul the block and get back destination dst = symb_exec.eval_updt_irblock(irb, step=step) # Add constraint if hist_nb < history_size: - next_label = history[hist_nb] - expected = symb_exec.eval_expr(ExprLoc(next_label, size)) + next_loc_key = history[hist_nb] + expected = symb_exec.eval_expr(ExprLoc(next_loc_key, size)) solver.add(self._gen_path_constraints(translator, dst, expected)) # Save the solver self._solver = solver @@ -411,17 +412,17 @@ class FollowExpr(object): return '%s(%r, %r)' % (self.__class__.__name__, self.follow, self.element) @staticmethod - def to_depnodes(follow_exprs, label, line): + def to_depnodes(follow_exprs, loc_key, line): """Build a set of FollowExpr(DependencyNode) from the @follow_exprs set of FollowExpr @follow_exprs: set of FollowExpr - @label: AsmLabel instance + @loc_key: LocKey instance @line: integer """ dependencies = set() for follow_expr in follow_exprs: dependencies.add(FollowExpr(follow_expr.follow, - DependencyNode(label, + DependencyNode(loc_key, follow_expr.element, line))) return dependencies @@ -469,7 +470,7 @@ class DependencyGraph(object): self._cb_follow.append(lambda exprs: self._follow_exprs(exprs, follow_mem, follow_call)) - self._cb_follow.append(self._follow_nolabel) + self._cb_follow.append(self._follow_no_loc_key) @staticmethod def _follow_simp_expr(exprs): @@ -529,11 +530,11 @@ class DependencyGraph(object): return follow, nofollow @staticmethod - def _follow_nolabel(exprs): - """Do not follow labels""" + def _follow_no_loc_key(exprs): + """Do not follow loc_keys""" follow = set() for expr in exprs: - if expr.is_int() or expr.is_label(): + if expr.is_int() or expr.is_loc(): continue follow.add(expr) @@ -580,25 +581,25 @@ class DependencyGraph(object): """Follow dependencies tracked in @state in the current irbloc @state: instance of DependencyState""" - irb = self._ira.blocks[state.label] + irb = self._ira.blocks[state.loc_key] line_nb = len(irb) if state.line_nb is None else state.line_nb for cur_line_nb, assignblk in reversed(list(enumerate(irb[:line_nb]))): self._track_exprs(state, assignblk, cur_line_nb) - def get(self, label, elements, line_nb, heads): + def get(self, loc_key, elements, line_nb, heads): """Compute the dependencies of @elements at line number @line_nb in - the block named @label in the current IRA, before the execution of + the block named @loc_key in the current IRA, before the execution of this line. Dependency check stop if one of @heads is reached - @label: AsmLabel instance + @loc_key: LocKey instance @element: set of Expr instances @line_nb: int - @heads: set of AsmLabel instances + @heads: set of LocKey instances Return an iterator on DiGraph(DependencyNode) """ # Init the algorithm inputs = {element: set() for element in elements} - initial_state = DependencyState(label, inputs, line_nb) + initial_state = DependencyState(loc_key, inputs, line_nb) todo = set([initial_state]) done = set() dpResultcls = DependencyResultImplicit if self._implicit else DependencyResult @@ -611,8 +612,8 @@ class DependencyGraph(object): continue done.add(done_state) if (not state.pending or - state.label in heads or - not self._ira.graph.predecessors(state.label)): + state.loc_key in heads or + not self._ira.graph.predecessors(state.loc_key)): yield dpResultcls(self._ira, initial_state, state, elements) if not state.pending: continue @@ -622,16 +623,16 @@ class DependencyGraph(object): state.pending[self._ira.IRDst] = set() # Propagate state to parents - for pred in self._ira.graph.predecessors_iter(state.label): + for pred in self._ira.graph.predecessors_iter(state.loc_key): todo.add(state.extend(pred)) def get_from_depnodes(self, depnodes, heads): """Alias for the get() method. Use the attributes of @depnodes as argument. - PRE: Labels and lines of depnodes have to be equals + PRE: Loc_Keys and lines of depnodes have to be equals @depnodes: set of DependencyNode instances - @heads: set of AsmLabel instances + @heads: set of LocKey instances """ lead = list(depnodes)[0] elements = set(depnode.element for depnode in depnodes) - return self.get(lead.label, elements, lead.line_nb, heads) + return self.get(lead.loc_key, elements, lead.line_nb, heads) diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py index 66caffc9..0502ea42 100644 --- a/miasm2/analysis/dse.py +++ b/miasm2/analysis/dse.py @@ -190,7 +190,7 @@ class DSEEngine(object): self.jitter.exec_cb = self.callback # Clean jit cache to avoid multi-line basic blocks already jitted - self.jitter.jit.lbl2jitbloc.clear() + self.jitter.jit.loc_key_to_jit_block.clear() def attach(self, emulator): """Attach the DSE to @emulator @@ -219,7 +219,7 @@ class DSEEngine(object): def handle(self, cur_addr): r"""Handle destination @cur_addr: Expr of the next address in concrete execution - /!\ cur_addr may be a lbl_gen + /!\ cur_addr may be a loc_key In this method, self.symb is in the "just before branching" state """ diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py index 8d4ab052..a57e585f 100644 --- a/miasm2/arch/aarch64/arch.py +++ b/miasm2/arch/aarch64/arch.py @@ -9,7 +9,6 @@ from collections import defaultdict from miasm2.core.bin_stream import bin_stream import regs as regs_module from regs import * -from miasm2.core.asmblock import AsmLabel from miasm2.core.cpu import log as log_cpu from miasm2.expression.modint import uint32, uint64, mod_size2int from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp @@ -277,8 +276,8 @@ class aarch64_arg(m_arg): if isinstance(value.name, ExprId): fixed_size.add(value.name.size) return value.name - label = symbol_pool.getby_name_create(value.name) - return ExprLoc(label.loc_key, size_hint) + loc_key = symbol_pool.getby_name_create(value.name) + return ExprLoc(loc_key, size_hint) if isinstance(value, AstInt): assert size_hint is not None return ExprInt(value.value, size_hint) @@ -315,9 +314,9 @@ class instruction_aarch64(instruction): wb = False if expr.is_id() or expr.is_int(): return str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - return str(symbol_pool.loc_key_to_label(expr.loc_key)) + return symbol_pool.str_loc_key(expr.loc_key) else: return str(expr) elif isinstance(expr, m2_expr.ExprOp) and expr.op in shift_expr: @@ -375,8 +374,8 @@ class instruction_aarch64(instruction): if not expr.is_int(): return addr = expr.arg + self.offset - label = symbol_pool.getby_offset_create(addr) - self.args[index] = m2_expr.ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + self.args[index] = m2_expr.ExprLoc(loc_key, expr.size) def breakflow(self): return self.name in BRCOND + ["BR", "BLR", "RET", "ERET", "DRPS", "B", "BL"] diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index 1a213b35..ad582878 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -593,14 +593,14 @@ def udiv(arg1, arg2, arg3): @sbuild.parse def cbz(arg1, arg2): - dst = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) if arg1 else arg2 + dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2 PC = dst ir.IRDst = dst @sbuild.parse def cbnz(arg1, arg2): - dst = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -609,7 +609,7 @@ def cbnz(arg1, arg2): def tbz(arg1, arg2, arg3): bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 dst = m2_expr.ExprId( - ir.get_next_label(instr), 64) if arg1 & bitmask else arg3 + ir.get_next_loc_key(instr), 64) if arg1 & bitmask else arg3 PC = dst ir.IRDst = dst @@ -618,21 +618,21 @@ def tbz(arg1, arg2, arg3): def tbnz(arg1, arg2, arg3): bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 dst = arg3 if arg1 & bitmask else m2_expr.ExprId( - ir.get_next_label(instr), 64) + ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @sbuild.parse def b_ne(arg1): - dst = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) if zf else arg1 + dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if zf else arg1 PC = dst ir.IRDst = dst @sbuild.parse def b_eq(arg1): - dst = arg1 if zf else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if zf else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -640,7 +640,7 @@ def b_eq(arg1): @sbuild.parse def b_ge(arg1): cond = cond2expr['GE'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -648,7 +648,7 @@ def b_ge(arg1): @sbuild.parse def b_gt(arg1): cond = cond2expr['GT'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -656,7 +656,7 @@ def b_gt(arg1): @sbuild.parse def b_cc(arg1): cond = cond2expr['CC'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -664,7 +664,7 @@ def b_cc(arg1): @sbuild.parse def b_cs(arg1): cond = cond2expr['CS'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -672,7 +672,7 @@ def b_cs(arg1): @sbuild.parse def b_hi(arg1): cond = cond2expr['HI'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -680,7 +680,7 @@ def b_hi(arg1): @sbuild.parse def b_le(arg1): cond = cond2expr['LE'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -688,7 +688,7 @@ def b_le(arg1): @sbuild.parse def b_ls(arg1): cond = cond2expr['LS'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -696,7 +696,7 @@ def b_ls(arg1): @sbuild.parse def b_lt(arg1): cond = cond2expr['LT'] - dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst @@ -732,7 +732,7 @@ def br(arg1): def blr(arg1): PC = arg1 ir.IRDst = arg1 - LR = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, 64) + LR = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) @sbuild.parse def nop(): @@ -877,7 +877,7 @@ class ir_aarch64l(IntermediateRepresentation): src = self.expr_fix_regs_for_mode(src) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, assignblk.instr)) - return IRBlock(irblock.label, irs) + return IRBlock(irblock.loc_key, irs) def mod_pc(self, instr, instr_ir, extra_ir): "Replace PC by the instruction's offset" @@ -908,7 +908,7 @@ class ir_aarch64l(IntermediateRepresentation): new_dsts = {dst:src for dst, src in assignblk.iteritems() if dst not in regs_to_fix} irs.append(AssignBlock(new_dsts, assignblk.instr)) - new_irblocks.append(IRBlock(irblock.label, irs)) + new_irblocks.append(IRBlock(irblock.loc_key, irs)) return instr_ir, new_irblocks diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index 204bf1b0..17b57ba4 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -347,9 +347,9 @@ class instruction_arm(instruction): wb = False if expr.is_id() or expr.is_int(): return str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - return str(symbol_pool.loc_key_to_label(expr.loc_key)) + return symbol_pool.str_loc_key(expr.loc_key) else: return str(expr) if isinstance(expr, ExprOp) and expr.op in expr2shift_dct: @@ -430,8 +430,8 @@ class instruction_arm(instruction): addr = expr.arg + self.offset else: addr = expr.arg + self.offset - label = symbol_pool.getby_offset_create(addr) - self.args[0] = ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name in conditional_branch + unconditional_branch: @@ -512,8 +512,8 @@ class instruction_armt(instruction_arm): else: addr = expr.arg + self.offset - label = symbol_pool.getby_offset_create(addr) - dst = ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + dst = ExprLoc(loc_key, expr.size) if self.name in ["CBZ", "CBNZ"]: self.args[1] = dst @@ -780,8 +780,8 @@ class arm_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - label = symbol_pool.getby_name_create(arg.name) - return ExprLoc(label.loc_key, 32) + loc_key = symbol_pool.getby_name_create(arg.name) + return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args] if None in args: diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py index 586fa903..956a894b 100644 --- a/miasm2/arch/arm/disasm.py +++ b/miasm2/arch/arm/disasm.py @@ -24,7 +24,8 @@ def cb_arm_fix_call(mn, cur_bloc, symbol_pool, offsets_to_dis, *args, **kwargs): return if not l2.args[1] in values: return - cur_bloc.add_cst(l1.offset + 4, AsmConstraint.c_next, symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(l1.offset + 4) + cur_bloc.add_cst(loc_key_cst, AsmConstraint.c_next, symbol_pool) offsets_to_dis.add(l1.offset + 4) cb_arm_funcs = [cb_arm_fix_call] diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 0b67dd2a..c80e9826 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -441,16 +441,16 @@ def sdiv(ir, instr, a, b, c=None): if c is None: b, c = a, b - lbl_div = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_except = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size) + loc_div = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_except = ExprId(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) - e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except))) + e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) - do_except.append(ExprAff(ir.IRDst, lbl_next)) - blk_except = IRBlock(lbl_except.name.loc_key, [AssignBlock(do_except, instr)]) + do_except.append(ExprAff(ir.IRDst, loc_next)) + blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) @@ -461,8 +461,8 @@ def sdiv(ir, instr, a, b, c=None): if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) - do_div.append(ExprAff(ir.IRDst, lbl_next)) - blk_div = IRBlock(lbl_div.name.loc_key, [AssignBlock(do_div, instr)]) + do_div.append(ExprAff(ir.IRDst, loc_next)) + blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except] @@ -474,16 +474,16 @@ def udiv(ir, instr, a, b, c=None): - lbl_div = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_except = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size) + loc_div = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_except = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) - e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except))) + e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) - do_except.append(ExprAff(ir.IRDst, lbl_next)) - blk_except = IRBlock(lbl_except.name.loc_key, [AssignBlock(do_except, instr)]) + do_except.append(ExprAff(ir.IRDst, loc_next)) + blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("udiv", b, c) @@ -493,8 +493,8 @@ def udiv(ir, instr, a, b, c=None): if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) - do_div.append(ExprAff(ir.IRDst, lbl_next)) - blk_div = IRBlock(lbl_div.name.loc_key, [AssignBlock(do_div, instr)]) + do_div.append(ExprAff(ir.IRDst, loc_next)) + blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except] @@ -932,17 +932,17 @@ def pop(ir, instr, a): def cbz(ir, instr, a, b): e = [] - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 32) - e.append(ExprAff(ir.IRDst, ExprCond(a, lbl_next_expr, b))) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 32) + e.append(ExprAff(ir.IRDst, ExprCond(a, loc_next_expr, b))) return e, [] def cbnz(ir, instr, a, b): e = [] - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 32) - e.append(ir.IRDst, ExprCond(a, b, lbl_next_expr)) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 32) + e.append(ir.IRDst, ExprCond(a, b, loc_next_expr)) return e, [] @@ -1267,12 +1267,12 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 32) - lbl_do = ir.gen_label() - lbl_do_expr = ExprLoc(lbl_do.loc_key, 32) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 32) + loc_do = ir.symbol_pool.gen_loc_key() + loc_do_expr = ExprLoc(loc_do, 32) - dst_cond = ExprCond(cond, lbl_do_expr, lbl_next_expr) + dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) assert(isinstance(instr_ir, list)) has_irdst = False @@ -1281,8 +1281,8 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): has_irdst = True break if not has_irdst: - instr_ir.append(ExprAff(ir.IRDst, lbl_next_expr)) - e_do = IRBlock(lbl_do.loc_key, [AssignBlock(instr_ir, instr)]) + instr_ir.append(ExprAff(ir.IRDst, loc_next_expr)) + e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)]) e = [ExprAff(ir.IRDst, dst_cond)] return e, [e_do] + extra_ir @@ -1532,7 +1532,7 @@ class ir_arml(IntermediateRepresentation): raise ValueError("IT name invalid %s" % instr) return out, instr.args[0] - def do_it_block(self, label, index, block, assignments, gen_pc_updt): + def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] @@ -1544,14 +1544,14 @@ class ir_arml(IntermediateRepresentation): ir_blocks_all = [] # Gen dummy irblock for IT instr - label_next = self.get_next_label(instr) - dst = ExprAff(self.IRDst, ExprId(label_next, 32)) + loc_next = self.get_next_loc_key(instr) + dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) - irblock = IRBlock(label.loc_key, assignments) + irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) - label = label_next + loc = loc_next assignments = [] for hint in it_hints: irblocks = [] @@ -1559,33 +1559,33 @@ class ir_arml(IntermediateRepresentation): instr = block.lines[index] # Add conditionnal jump to current irblock - label_do = self.symbol_pool.gen_label() - label_next = self.get_next_label(instr) + loc_do = self.symbol_pool.gen_loc_key() + loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq - dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprId(label_do, 32), ExprId(label_next, 32))) + dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) - irblock = IRBlock(label.loc_key, assignments) + irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] - label = label_do + loc = loc_do split = self.add_instr_to_irblock(block, instr, assignments, irblocks, gen_pc_updt) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) - dst = ExprAff(self.IRDst, ExprId(label_next, 32)) + dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) - irblock = IRBlock(label.loc_key, assignments) + irblock = IRBlock(loc, assignments) irblocks.append(irblock) - label = label_next + loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all @@ -1599,7 +1599,7 @@ class ir_arml(IntermediateRepresentation): it_hints = None it_cond = None - label = block.label + label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 @@ -1608,7 +1608,7 @@ class ir_arml(IntermediateRepresentation): instr = block.lines[index] if label is None: assignments = [] - label = self.get_instr_label(instr) + label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: @@ -1619,15 +1619,15 @@ class ir_arml(IntermediateRepresentation): split = self.add_instr_to_irblock(block, instr, assignments, ir_blocks_all, gen_pc_updt) if split: - ir_blocks_all.append(IRBlock(label.loc_key, assignments)) + ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: - ir_blocks_all.append(IRBlock(label.loc_key, assignments)) + ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_block(block, ir_blocks_all) for irblock in new_ir_blocks_all: - self.blocks[irblock.label] = irblock + self.blocks[irblock.loc_key] = irblock return new_ir_blocks_all diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py index d1b0a8eb..939ce5b0 100644 --- a/miasm2/arch/mips32/arch.py +++ b/miasm2/arch/mips32/arch.py @@ -63,9 +63,9 @@ class instruction_mips32(cpu.instruction): def arg2str(expr, index=None, symbol_pool=None): if expr.is_id() or expr.is_int(): return str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - return str(symbol_pool.loc_key_to_label(expr.loc_key)) + return symbol_pool.str_loc_key(expr.loc_key) else: return str(expr) assert(isinstance(expr, ExprMem)) @@ -107,8 +107,8 @@ class instruction_mips32(cpu.instruction): if not isinstance(expr, ExprInt): return addr = expr.arg + self.offset - label = symbol_pool.getby_offset_create(addr) - self.args[ndx] = ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + self.args[ndx] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name == 'BREAK': @@ -265,8 +265,8 @@ class mips32_arg(cpu.m_arg): return arg.name if arg.name in gpregs.str: return None - label = symbol_pool.getby_name_create(arg.name) - return ExprLoc(label.loc_key, 32) + loc_key = symbol_pool.getby_name_create(arg.name) + return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args] if None in args: diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py index b17ddbd2..b6d92ee0 100644 --- a/miasm2/arch/mips32/ira.py +++ b/miasm2/arch/mips32/ira.py @@ -27,10 +27,10 @@ class ir_a_mips32l(ir_mips32l, ira): if pc_val is None or lr_val is None: new_irblocks.append(irb) continue - if lr_val.is_label(): - label = self.symbol_pool.loc_key_to_label(lr_valloc_key) - if label.offset is not None: - lr_val = ExprInt(label.offset, 32) + if lr_val.is_loc(): + offset = self.symbol_pool.loc_key_to_offset(lr_val.loc_key) + if offset is not None: + lr_val = ExprInt(offset, 32) if not lr_val.is_int(): continue diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py index b3cfecbc..180f8b0a 100644 --- a/miasm2/arch/mips32/jit.py +++ b/miasm2/arch/mips32/jit.py @@ -57,10 +57,10 @@ class mipsCGen(CGen): self.ir_arch.pc] assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32) # Replace IRDst with next instruction - dst = self.ir_arch.get_next_instr(assignblock.instr) - assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(dst.loc_key, 32) + dst_loc_key = self.ir_arch.get_next_instr(assignblock.instr) + assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(dst_loc_key, 32) irs.append(AssignBlock(assignments, assignblock.instr)) - irblocks[blk_idx] = IRBlock(irblock.label, irs) + irblocks[blk_idx] = IRBlock(irblock.loc_key, irs) return irblocks_list @@ -69,12 +69,13 @@ class mipsCGen(CGen): Generate the C code for the final block instruction """ - lbl = self.get_block_post_label(block) - out = (self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), + loc_key = self.get_block_post_label(block) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key) + out = (self.CODE_RETURN_NO_EXCEPTION % (self.loc_key_to_jitlabel(loc_key), self.C_PC, m2_expr.ExprId('branch_dst_irdst', 32), m2_expr.ExprId('branch_dst_irdst', 32), - self.id_to_c(m2_expr.ExprInt(lbl.offset, 32))) + self.id_to_c(m2_expr.ExprInt(offset, 32))) ).split('\n') return out diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py index bb0f812d..fd4fa655 100644 --- a/miasm2/arch/mips32/sem.py +++ b/miasm2/arch/mips32/sem.py @@ -35,7 +35,7 @@ def jal(arg1): "Jumps to the calculated address @arg1 and stores the return address in $RA" PC = arg1 ir.IRDst = arg1 - RA = ExprLoc(ir.get_next_break_label(instr).loc_key, RA.size) + RA = ExprLoc(ir.get_next_break_loc_key(instr), RA.size) @sbuild.parse def jalr(arg1, arg2): @@ -43,13 +43,13 @@ def jalr(arg1, arg2): address in another register @arg2""" PC = arg1 ir.IRDst = arg1 - arg2 = ExprLoc(ir.get_next_break_label(instr).loc_key, arg2.size) + arg2 = ExprLoc(ir.get_next_break_loc_key(instr), arg2.size) @sbuild.parse def bal(arg1): PC = arg1 ir.IRDst = arg1 - RA = ExprLoc(ir.get_next_break_label(instr).loc_key, RA.size) + RA = ExprLoc(ir.get_next_break_loc_key(instr), RA.size) @sbuild.parse def l_b(arg1): @@ -76,7 +76,7 @@ def lb(arg1, arg2): @sbuild.parse def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" - dst = ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) if arg1 - arg2 else arg3 + dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 - arg2 else arg3 PC = dst ir.IRDst = dst @@ -84,7 +84,7 @@ def beq(arg1, arg2, arg3): def bgez(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" - dst = ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) if arg1.msb() else arg2 + dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1.msb() else arg2 PC = dst ir.IRDst = dst @@ -92,7 +92,7 @@ def bgez(arg1, arg2): def bne(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" - dst = arg3 if arg1 - arg2 else ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) + dst = arg3 if arg1 - arg2 else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst ir.IRDst = dst @@ -230,7 +230,7 @@ def seh(arg1, arg2): @sbuild.parse def bltz(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than zero""" - dst_o = arg2 if arg1.msb() else ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) + dst_o = arg2 if arg1.msb() else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o @@ -238,7 +238,7 @@ def bltz(arg1, arg2): def blez(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = (i1(1) if arg1 else i1(0)) | arg1.msb() - dst_o = arg2 if cond else ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) + dst_o = arg2 if cond else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o @@ -246,7 +246,7 @@ def blez(arg1, arg2): def bgtz(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = (i1(1) if arg1 else i1(0)) | arg1.msb() - dst_o = ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) if cond else arg2 + dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if cond else arg2 PC = dst_o ir.IRDst = dst_o @@ -346,13 +346,13 @@ def c_le_d(arg1, arg2, arg3): @sbuild.parse def bc1t(arg1, arg2): - dst_o = arg2 if arg1 else ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) + dst_o = arg2 if arg1 else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o @sbuild.parse def bc1f(arg1, arg2): - dst_o = ExprLoc(ir.get_next_break_label(instr).loc_key, ir.IRDst.size) if arg1 else arg2 + dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 else arg2 PC = dst_o ir.IRDst = dst_o @@ -415,22 +415,22 @@ def ehb(arg1): def teq(ir, instr, arg1, arg2): e = [] - lbl_except, lbl_except_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprId(lbl_next, ir.IRDst.size) + loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) do_except = [] do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt( EXCEPT_DIV_BY_ZERO, exception_flags.size))) - do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - blk_except = IRBlock(lbl_except.index, [AssignBlock(do_except, instr)]) + do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)]) cond = arg1 - arg2 e = [] e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(cond, lbl_next_expr, lbl_except_expr))) + m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr))) return e, [blk_except] @@ -492,7 +492,7 @@ class ir_mips32l(IntermediateRepresentation): def get_next_instr(self, instr): return self.symbol_pool.getby_offset_create(instr.offset + 4) - def get_next_break_label(self, instr): + def get_next_break_loc_key(self, instr): return self.symbol_pool.getby_offset_create(instr.offset + 8) class ir_mips32b(ir_mips32l): diff --git a/miasm2/arch/msp430/arch.py b/miasm2/arch/msp430/arch.py index 3248a4bc..1842f577 100644 --- a/miasm2/arch/msp430/arch.py +++ b/miasm2/arch/msp430/arch.py @@ -69,8 +69,8 @@ class msp430_arg(m_arg): index = gpregs.str.index(name) reg = gpregs.expr[index] return reg - label = symbol_pool.getby_name_create(value.name) - return ExprLoc(label.loc_key, 16) + loc_key = symbol_pool.getby_name_create(value.name) + return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in value.args] if None in args: @@ -107,9 +107,9 @@ class instruction_msp430(instruction): o = str(expr) elif isinstance(expr, ExprInt): o = str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - return str(symbol_pool.loc_key_to_label(expr.loc_key)) + return symbol_pool.str_loc_key(expr.loc_key) else: return str(expr) elif isinstance(expr, ExprOp) and expr.op == "autoinc": @@ -138,8 +138,8 @@ class instruction_msp430(instruction): else: addr = expr.arg + int(self.offset) - label = symbol_pool.getby_offset_create(addr) - self.args[0] = ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name in conditional_branch + unconditional_branch: diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py index 42f6474e..877c2a70 100644 --- a/miasm2/arch/msp430/sem.py +++ b/miasm2/arch/msp430/sem.py @@ -239,10 +239,10 @@ def push_w(ir, instr, a): def call(ir, instr, a): e, a, dummy = mng_autoinc(a, None, 16) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) - e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), lbl_next_expr)) + e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), loc_next_expr)) e.append(ExprAff(SP, SP - ExprInt(2, 16))) e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) @@ -275,56 +275,56 @@ def cmp_b(ir, instr, a, b): def jz(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(zf, a, lbl_next_expr))) - e.append(ExprAff(ir.IRDst, ExprCond(zf, a, lbl_next_expr))) + e.append(ExprAff(PC, ExprCond(zf, a, loc_next_expr))) + e.append(ExprAff(ir.IRDst, ExprCond(zf, a, loc_next_expr))) return e, [] def jnz(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(zf, lbl_next_expr, a))) - e.append(ExprAff(ir.IRDst, ExprCond(zf, lbl_next_expr, a))) + e.append(ExprAff(PC, ExprCond(zf, loc_next_expr, a))) + e.append(ExprAff(ir.IRDst, ExprCond(zf, loc_next_expr, a))) return e, [] def jl(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(nf ^ of, a, lbl_next_expr))) - e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, lbl_next_expr))) + e.append(ExprAff(PC, ExprCond(nf ^ of, a, loc_next_expr))) + e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, loc_next_expr))) return e, [] def jc(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(cf, a, lbl_next_expr))) - e.append(ExprAff(ir.IRDst, ExprCond(cf, a, lbl_next_expr))) + e.append(ExprAff(PC, ExprCond(cf, a, loc_next_expr))) + e.append(ExprAff(ir.IRDst, ExprCond(cf, a, loc_next_expr))) return e, [] def jnc(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(cf, lbl_next_expr, a))) - e.append(ExprAff(ir.IRDst, ExprCond(cf, lbl_next_expr, a))) + e.append(ExprAff(PC, ExprCond(cf, loc_next_expr, a))) + e.append(ExprAff(ir.IRDst, ExprCond(cf, loc_next_expr, a))) return e, [] def jge(ir, instr, a): - lbl_next = ir.get_next_label(instr) - lbl_next_expr = ExprLoc(lbl_next.loc_key, 16) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAff(PC, ExprCond(nf ^ of, lbl_next_expr, a))) - e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, lbl_next_expr, a))) + e.append(ExprAff(PC, ExprCond(nf ^ of, loc_next_expr, a))) + e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, loc_next_expr, a))) return e, [] diff --git a/miasm2/arch/ppc/arch.py b/miasm2/arch/ppc/arch.py index 429fd22d..5336ea21 100644 --- a/miasm2/arch/ppc/arch.py +++ b/miasm2/arch/ppc/arch.py @@ -5,7 +5,6 @@ from miasm2.expression.expression import * from miasm2.core.cpu import * from collections import defaultdict from miasm2.core.bin_stream import bin_stream -from miasm2.core.asmblock import asm_label import miasm2.arch.ppc.regs as regs_module from miasm2.arch.ppc.regs import * from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp @@ -41,8 +40,8 @@ class ppc_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - label = symbol_pool.getby_name_create(arg.name) - return ExprLoc(label.loc_key, 32) + loc_key = symbol_pool.getby_name_create(arg.name) + return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args] if None in args: @@ -132,8 +131,8 @@ class instruction_ppc(instruction): ad = e.arg + self.offset else: ad = e.arg - label = symbol_pool.getby_offset_create(ad) - s = ExprLoc(label.loc_key, e.size) + loc_key = symbol_pool.getby_offset_create(ad) + s = ExprLoc(loc_key, e.size) self.args[address_index] = s def breakflow(self): diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py index 775e24d3..8ddb43ef 100644 --- a/miasm2/arch/ppc/sem.py +++ b/miasm2/arch/ppc/sem.py @@ -606,21 +606,21 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None): ret.append(ExprAff(arg2, address)) if is_stwcx: - lbl_do = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_dont = ExprId(ir.gen_label(), ir.IRDst.size) - lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size) + loc_do = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_dont = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size) + loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) flags = [ ExprAff(CR0_LT, ExprInt(0,1)), ExprAff(CR0_GT, ExprInt(0,1)), ExprAff(CR0_SO, XER_SO)] ret += flags ret.append(ExprAff(CR0_EQ, ExprInt(1,1))) - ret.append(ExprAff(ir.IRDst, lbl_next)) + ret.append(ExprAff(ir.IRDst, loc_next)) dont = flags + [ ExprAff(CR0_EQ, ExprInt(0,1)), - ExprAff(ir.IRDst, lbl_next) ] - additional_ir = [ IRBlock(lbl_do.name, [ AssignBlock(ret) ]), - IRBlock(lbl_dont.name, [ AssignBlock(dont) ]) ] + ExprAff(ir.IRDst, loc_next) ] + additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]), + IRBlock(loc_dont, [ AssignBlock(dont) ]) ] ret = [ ExprAff(reserve, ExprInt(0, 1)), - ExprAff(ir.IRDst, ExprCond(reserve, lbl_do, lbl_dont)) ] + ExprAff(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ] return ret, additional_ir @@ -691,7 +691,7 @@ def mn_bl(ir, instr, arg1, arg2 = None): if arg2 is not None: arg1 = arg2 dst = ir.get_next_instr(instr) - return [ ExprAff(LR, ExprLoc(dst.loc_key, 32)), + return [ ExprAff(LR, ExprLoc(dst, 32)), ExprAff(PC, arg1), ExprAff(ir.IRDst, arg1) ], [] @@ -729,13 +729,13 @@ def mn_do_cond_branch(ir, instr, dest): condition = cond_cond dst = ir.get_next_instr(instr) dest_expr = ExprCond(condition, dest, - ExprLoc(dst.loc_key, 32)) + ExprLoc(dst, 32)) else: dest_expr = dest if instr.name[-1] == 'L' or instr.name[-2:-1] == 'LA': dst = ir.get_next_instr(instr) - ret.append(ExprAff(LR, ExprLoc(dst.loc_key, 32))) + ret.append(ExprAff(LR, ExprLoc(dst, 32))) ret.append(ExprAff(PC, dest_expr)) ret.append(ExprAff(ir.IRDst, dest_expr)) @@ -919,6 +919,6 @@ class ir_ppc32b(IntermediateRepresentation): l = self.symbol_pool.getby_offset_create(instr.offset + 4) return l - def get_next_break_label(self, instr): + def get_next_break_loc_key(self, instr): l = self.symbol_pool.getby_offset_create(instr.offset + 4) return l diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py index dd25cb90..477edeaf 100644 --- a/miasm2/arch/sh4/arch.py +++ b/miasm2/arch/sh4/arch.py @@ -102,8 +102,8 @@ class sh4_arg(m_arg): return arg.name if arg.name in gpregs.str: return None - label = symbol_pool.getby_name_create(arg.name) - return ExprLoc(label.loc_key, 32) + loc_key = symbol_pool.getby_name_create(arg.name) + return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args] if None in args: @@ -409,9 +409,9 @@ class instruction_sh4(instruction): def arg2str(expr, index=None, symbol_pool=None): if isinstance(expr, ExprId) or isinstance(expr, ExprInt): return str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - return str(symbol_pool.loc_key_to_label(expr.loc_key)) + return symbol_pool.str_loc_key(expr.loc_key) else: return str(expr) assert(isinstance(expr, ExprMem)) diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 4a044d6a..2be64c0e 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -7,7 +7,6 @@ from miasm2.core.cpu import * from collections import defaultdict import miasm2.arch.x86.regs as regs_module from miasm2.arch.x86.regs import * -from miasm2.core.asmblock import AsmLabel from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstMem, AstOp @@ -273,8 +272,8 @@ class x86_arg(m_arg): if value.name in ["FAR"]: return None - label = symbol_pool.getby_name_create(value.name) - return ExprLoc(label.loc_key, size_hint) + loc_key = symbol_pool.getby_name_create(value.name) + return ExprLoc(loc_key, size_hint) if isinstance(value, AstOp): # First pass to retreive fixed_size if value.op == "segm": @@ -477,8 +476,8 @@ class instruction_x86(instruction): if not expr.is_int(): return addr = expr.arg + int(self.offset) - label = symbol_pool.getby_offset_create(addr) - self.args[0] = ExprLoc(label.loc_key, expr.size) + loc_key = symbol_pool.getby_offset_create(addr) + self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name in conditional_branch + unconditional_branch: @@ -515,8 +514,8 @@ class instruction_x86(instruction): def getdstflow(self, symbol_pool): if self.additional_info.g1.value & 6 and self.name in repeat_mn: addr = int(self.offset) - label = symbol_pool.getby_offset_create(addr) - return [ExprLoc(label.loc_key, self.v_opmode())] + loc_key = symbol_pool.getby_offset_create(addr) + return [ExprLoc(loc_key, self.v_opmode())] return [self.args[0]] def get_symbol_size(self, symbol, symbol_pool): @@ -563,9 +562,9 @@ class instruction_x86(instruction): def arg2str(expr, index=None, symbol_pool=None): if expr.is_id() or expr.is_int(): o = str(expr) - elif expr.is_label(): + elif expr.is_loc(): if symbol_pool is not None: - o = str(symbol_pool.loc_key_to_label(expr.loc_key)) + o = symbol_pool.str_loc_key(expr.loc_key) else: o = str(expr) elif ((isinstance(expr, ExprOp) and expr.op == 'far' and diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index d524af86..d53677be 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -240,13 +240,13 @@ def gen_jcc(ir, instr, cond, dst, jmp_if): e = [] meip = mRIP[ir.IRDst.size] - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, dst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, dst.size) if jmp_if: - dstA, dstB = dst, lbl_next_expr + dstA, dstB = dst, loc_next_expr else: - dstA, dstB = lbl_next_expr, dst + dstA, dstB = loc_next_expr, dst mn_dst = m2_expr.ExprCond(cond, dstA.zeroExtend(ir.IRDst.size), dstB.zeroExtend(ir.IRDst.size)) @@ -262,18 +262,18 @@ def gen_fcmov(ir, instr, cond, arg1, arg2, mov_if): @cond: condition @mov_if: invert condition if False""" - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_skip = ir.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, ir.IRDst.size) + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_skip = ir.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size) if mov_if: - dstA, dstB = lbl_do_expr, lbl_skip_expr + dstA, dstB = loc_do_expr, loc_skip_expr else: - dstA, dstB = lbl_skip_expr, lbl_do_expr + dstA, dstB = loc_skip_expr, loc_do_expr e = [] e_do, extra_irs = [m2_expr.ExprAff(arg1, arg2)], [] - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip_expr)) + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr)) e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(cond, dstA, dstB))) - return e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)])] + return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])] def gen_cmov(ir, instr, cond, dst, src, mov_if): @@ -283,18 +283,18 @@ def gen_cmov(ir, instr, cond, dst, src, mov_if): @cond: condition @mov_if: invert condition if False""" - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_skip = ir.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, ir.IRDst.size) + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_skip = ir.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size) if mov_if: - dstA, dstB = lbl_do_expr, lbl_skip_expr + dstA, dstB = loc_do_expr, loc_skip_expr else: - dstA, dstB = lbl_skip_expr, lbl_do_expr + dstA, dstB = loc_skip_expr, loc_do_expr e = [] e_do, extra_irs = mov(ir, instr, dst, src) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip_expr)) + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr)) e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(cond, dstA, dstB))) - return e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)])] + return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])] def mov(_, instr, dst, src): @@ -508,14 +508,14 @@ def _rotate_tpl(ir, instr, dst, src, op, left=False): else: return ([], []) e = [] - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_skip = ir.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, ir.IRDst.size) + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_skip = ir.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip_expr)) + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr)) e.append(m2_expr.ExprAff( - ir.IRDst, m2_expr.ExprCond(shifter, lbl_do_expr, lbl_skip_expr))) - return (e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)])]) + ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr, loc_skip_expr))) + return (e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])]) def l_rol(ir, instr, dst, src): @@ -557,14 +557,14 @@ def rotate_with_carry_tpl(ir, instr, op, dst, src): else: return ([], []) e = [] - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_skip = ir.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, ir.IRDst.size) + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_skip = ir.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip_expr)) + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr)) e.append(m2_expr.ExprAff( - ir.IRDst, m2_expr.ExprCond(shifter, lbl_do_expr, lbl_skip_expr))) - return (e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)])]) + ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr, loc_skip_expr))) + return (e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])]) def rcl(ir, instr, dst, src): return rotate_with_carry_tpl(ir, instr, '<<<', dst, src) @@ -646,13 +646,13 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False, return [], [] e = [] - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_skip = ir.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, ir.IRDst.size) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip_expr)) - e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, lbl_do_expr, - lbl_skip_expr))) - return e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)])] + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_skip = ir.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size) + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr)) + e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr, + loc_skip_expr))) + return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])] def sar(ir, instr, dst, src): @@ -982,9 +982,9 @@ def bswap(_, instr, dst): def cmps(ir, instr, size): - lbl_df_0, lbl_df_0_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_df_1, lbl_df_1_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next_expr = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) src1 = mRSI[instr.mode][:instr.v_admode()] src2 = mRDI[instr.mode][:instr.v_admode()] @@ -1008,24 +1008,24 @@ def cmps(ir, instr, size): e0 = [] e0.append(m2_expr.ExprAff(src1, src1 + offset)) e0.append(m2_expr.ExprAff(src2, src2 + offset)) - e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e0 = IRBlock(lbl_df_0.loc_key, [AssignBlock(e0, instr)]) + e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)]) e1 = [] e1.append(m2_expr.ExprAff(src1, src1 - offset)) e1.append(m2_expr.ExprAff(src2, src2 - offset)) - e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e1 = IRBlock(lbl_df_1.loc_key, [AssignBlock(e1, instr)]) + e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)]) e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(df, lbl_df_1_expr, lbl_df_0_expr))) + m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr))) return e, [e0, e1] def scas(ir, instr, size): - lbl_df_0, lbl_df_0_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_df_1, lbl_df_1_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next_expr = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) src = mRDI[instr.mode][:instr.v_admode()] @@ -1045,16 +1045,16 @@ def scas(ir, instr, size): e0 = [] e0.append(m2_expr.ExprAff(src, src + offset)) - e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e0 = IRBlock(lbl_df_0.loc_key, [AssignBlock(e0, instr)]) + e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)]) e1 = [] e1.append(m2_expr.ExprAff(src, src - offset)) - e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e1 = IRBlock(lbl_df_1.loc_key, [AssignBlock(e1, instr)]) + e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)]) e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(df, lbl_df_1_expr, lbl_df_0_expr))) + m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr))) return e, [e0, e1] @@ -1194,7 +1194,7 @@ def call(ir, instr, dst): meip = mRIP[ir.IRDst.size] opmode, admode = s, instr.v_admode() myesp = mRSP[instr.mode][:opmode] - n = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) if isinstance(dst, m2_expr.ExprOp): if dst.op == "segm": @@ -1439,7 +1439,7 @@ def loop(ir, instr, dst): admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) c = myecx - m2_expr.ExprInt(1, myecx.size) dst_o = m2_expr.ExprCond(c, dst.zeroExtend(ir.IRDst.size), @@ -1456,7 +1456,7 @@ def loopne(ir, instr, dst): admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size), m2_expr.ExprInt(1, 1), @@ -1478,7 +1478,7 @@ def loope(ir, instr, dst): admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size), m2_expr.ExprInt(1, 1), m2_expr.ExprInt(0, 1)) @@ -1515,25 +1515,25 @@ def div(ir, instr, src1): e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) - lbl_div, lbl_div_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_except, lbl_except_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, ir.IRDst.size) + loc_div, loc_div_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) do_div = [] do_div += e - do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - blk_div = IRBlock(lbl_div.loc_key, [AssignBlock(do_div, instr)]) + do_div.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + blk_div = IRBlock(loc_div, [AssignBlock(do_div, instr)]) do_except = [] do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt( EXCEPT_DIV_BY_ZERO, exception_flags.size))) - do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - blk_except = IRBlock(lbl_except.loc_key, [AssignBlock(do_except, instr)]) + do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)]) e = [] e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(src1, lbl_div_expr, lbl_except_expr))) + m2_expr.ExprCond(src1, loc_div_expr, loc_except_expr))) return e, [blk_div, blk_except] @@ -1562,25 +1562,25 @@ def idiv(ir, instr, src1): e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) - lbl_div, lbl_div_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_except, lbl_except_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, ir.IRDst.size) + loc_div, loc_div_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) do_div = [] do_div += e - do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - blk_div = IRBlock(lbl_div.loc_key, [AssignBlock(do_div, instr)]) + do_div.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + blk_div = IRBlock(loc_div, [AssignBlock(do_div, instr)]) do_except = [] do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt( EXCEPT_DIV_BY_ZERO, exception_flags.size))) - do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - blk_except = IRBlock(lbl_except.loc_key, [AssignBlock(do_except, instr)]) + do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)]) e = [] e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(src1, lbl_div_expr, lbl_except_expr))) + m2_expr.ExprCond(src1, loc_div_expr, loc_except_expr))) return e, [blk_div, blk_except] @@ -1722,9 +1722,9 @@ def cqo(_, instr): def stos(ir, instr, size): - lbl_df_0, lbl_df_0_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_df_1, lbl_df_1_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next_expr = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) addr_o = mRDI[instr.mode][:instr.v_admode()] addr = addr_o @@ -1741,25 +1741,25 @@ def stos(ir, instr, size): e0 = [] e0.append(m2_expr.ExprAff(addr_o, addr_p)) - e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e0 = IRBlock(lbl_df_0.loc_key, [AssignBlock(e0, instr)]) + e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)]) e1 = [] e1.append(m2_expr.ExprAff(addr_o, addr_m)) - e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e1 = IRBlock(lbl_df_1.loc_key, [AssignBlock(e1, instr)]) + e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)]) e = [] e.append(m2_expr.ExprAff(ir.ExprMem(addr, size), b)) e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(df, lbl_df_1_expr, lbl_df_0_expr))) + m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr))) return e, [e0, e1] def lods(ir, instr, size): - lbl_df_0, lbl_df_0_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_df_1, lbl_df_1_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next_expr = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e = [] addr_o = mRSI[instr.mode][:instr.v_admode()] @@ -1777,13 +1777,13 @@ def lods(ir, instr, size): e0 = [] e0.append(m2_expr.ExprAff(addr_o, addr_p)) - e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e0 = IRBlock(lbl_df_0.loc_key, [AssignBlock(e0, instr)]) + e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)]) e1 = [] e1.append(m2_expr.ExprAff(addr_o, addr_m)) - e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e1 = IRBlock(lbl_df_1.loc_key, [AssignBlock(e1, instr)]) + e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)]) e = [] if instr.mode == 64 and b.size == 32: @@ -1793,14 +1793,14 @@ def lods(ir, instr, size): e.append(m2_expr.ExprAff(b, ir.ExprMem(addr, size))) e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(df, lbl_df_1_expr, lbl_df_0_expr))) + m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr))) return e, [e0, e1] def movs(ir, instr, size): - lbl_df_0, lbl_df_0_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_df_1, lbl_df_1_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next_expr = m2_expr.ExprLoc(ir.get_next_label(instr).loc_key, ir.IRDst.size) + loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) dst = mRDI[instr.mode][:instr.v_admode()] src = mRSI[instr.mode][:instr.v_admode()] @@ -1824,17 +1824,17 @@ def movs(ir, instr, size): e0 = [] e0.append(m2_expr.ExprAff(src, src + offset)) e0.append(m2_expr.ExprAff(dst, dst + offset)) - e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e0 = IRBlock(lbl_df_0.loc_key, [AssignBlock(e0, instr)]) + e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)]) e1 = [] e1.append(m2_expr.ExprAff(src, src - offset)) e1.append(m2_expr.ExprAff(dst, dst - offset)) - e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - e1 = IRBlock(lbl_df_1.loc_key, [AssignBlock(e1, instr)]) + e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)]) e.append(m2_expr.ExprAff(ir.IRDst, - m2_expr.ExprCond(df, lbl_df_1_expr, lbl_df_0_expr))) + m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr))) return e, [e0, e1] @@ -2885,15 +2885,15 @@ def bsr_bsf(ir, instr, dst, src, op_func): ZF = 0 DEST = @op_func(SRC) """ - lbl_src_null, lbl_src_null_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_src_not_null, lbl_src_not_null_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, ir.IRDst.size) + loc_src_null, loc_src_null_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_src_not_null, loc_src_not_null_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) - aff_dst = m2_expr.ExprAff(ir.IRDst, lbl_next_expr) + aff_dst = m2_expr.ExprAff(ir.IRDst, loc_next_expr) e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(src, - lbl_src_not_null_expr, - lbl_src_null_expr))] + loc_src_not_null_expr, + loc_src_null_expr))] e_src_null = [] e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt(1, zf.size))) # XXX destination is undefined @@ -2904,8 +2904,8 @@ def bsr_bsf(ir, instr, dst, src, op_func): e_src_not_null.append(m2_expr.ExprAff(dst, op_func(src))) e_src_not_null.append(aff_dst) - return e, [IRBlock(lbl_src_null.loc_key, [AssignBlock(e_src_null, instr)]), - IRBlock(lbl_src_not_null.loc_key, [AssignBlock(e_src_not_null, instr)])] + return e, [IRBlock(loc_src_null, [AssignBlock(e_src_null, instr)]), + IRBlock(loc_src_not_null, [AssignBlock(e_src_not_null, instr)])] def bsf(ir, instr, dst, src): @@ -3935,10 +3935,10 @@ def pshufd(_, instr, dst, src, imm): def ps_rl_ll(ir, instr, dst, src, op, size): - lbl_zero, lbl_zero_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_do, lbl_do_expr = ir.gen_label_and_expr(ir.IRDst.size) - lbl_next = ir.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, ir.IRDst.size) + loc_zero, loc_zero_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) if src.size == 8: count = src.zeroExtend(dst.size) @@ -3951,8 +3951,8 @@ def ps_rl_ll(ir, instr, dst, src, op, size): test = expr_simp(count & m2_expr.ExprInt( ((1 << dst.size) - 1) ^ mask, dst.size)) e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(test, - lbl_zero_expr, - lbl_do_expr))] + loc_zero_expr, + loc_do_expr))] slices = [] for i in xrange(0, dst.size, size): @@ -3965,12 +3965,12 @@ def ps_rl_ll(ir, instr, dst, src, op, size): return [m2_expr.ExprAff(dst, m2_expr.ExprInt(0, dst.size))], [] e_zero = [m2_expr.ExprAff(dst, m2_expr.ExprInt(0, dst.size)), - m2_expr.ExprAff(ir.IRDst, lbl_next_expr)] + m2_expr.ExprAff(ir.IRDst, loc_next_expr)] e_do = [] e.append(m2_expr.ExprAff(dst[0:dst.size], m2_expr.ExprCompose(*slices))) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr)) - return e, [IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)]), - IRBlock(lbl_zero.loc_key, [AssignBlock(e_zero, instr)])] + e_do.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr)) + return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)]), + IRBlock(loc_zero, [AssignBlock(e_zero, instr)])] def psrlw(ir, instr, dst, src): @@ -4474,7 +4474,8 @@ paddsw = vec_vertical_instr('+', 16, _saturation_add_signed) # Others SSE operations def maskmovq(ir, instr, src, mask): - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) blks = [] # For each possibility, check if a write is necessary @@ -4488,7 +4489,7 @@ def maskmovq(ir, instr, src, mask): for i, start in enumerate(xrange(0, mask.size, 8)): bit = mask[start + 7: start + 8] cur_label = check_labels[i] - next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr write_label = write_labels[i] check = m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(bit, @@ -4501,7 +4502,7 @@ def maskmovq(ir, instr, src, mask): for i, start in enumerate(xrange(0, mask.size, 8)): bit = mask[start + 7: start + 8] cur_label = write_labels[i] - next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size) # @8[DI/EDI/RDI + i] = src[byte i] @@ -4513,7 +4514,7 @@ def maskmovq(ir, instr, src, mask): # If mask is null, bypass all e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(mask, check_labels[0], - lbl_next))] + loc_next_expr))] return e, blks @@ -5156,15 +5157,15 @@ class ir_x86_16(IntermediateRepresentation): c_cond = cond_dec | (zf ^ m2_expr.ExprInt(1, 1)) # gen while - lbl_do, lbl_do_expr = self.gen_label_and_expr(self.IRDst.size) - lbl_end, lbl_end_expr = self.gen_label_and_expr(self.IRDst.size) - lbl_skip = self.get_next_label(instr) - lbl_skip_expr = m2_expr.ExprLoc(lbl_skip.loc_key, self.IRDst.size) - lbl_next = self.get_next_label(instr) - lbl_next_expr = m2_expr.ExprLoc(lbl_next.loc_key, self.IRDst.size) - - fix_next_lbl = {lbl_next_expr: lbl_end_expr} - new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fix_next_lbl)) + loc_do, loc_do_expr = self.gen_loc_key_and_expr(self.IRDst.size) + loc_end, loc_end_expr = self.gen_loc_key_and_expr(self.IRDst.size) + loc_skip = self.get_next_loc_key(instr) + loc_skip_expr = m2_expr.ExprLoc(loc_skip, self.IRDst.size) + loc_next = self.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, self.IRDst.size) + + fix_next_loc = {loc_next_expr: loc_end_expr} + new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fix_next_loc)) for irblock in extra_ir] cond_bloc = [] @@ -5172,14 +5173,14 @@ class ir_x86_16(IntermediateRepresentation): c_reg - m2_expr.ExprInt(1, c_reg.size))) cond_bloc.append(m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_cond, - lbl_skip_expr, - lbl_do_expr))) - cond_bloc = IRBlock(lbl_end.loc_key, [AssignBlock(cond_bloc, instr)]) + loc_skip_expr, + loc_do_expr))) + cond_bloc = IRBlock(loc_end, [AssignBlock(cond_bloc, instr)]) e_do = instr_ir - c = IRBlock(lbl_do.loc_key, [AssignBlock(e_do, instr)]) - e_n = [m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_reg, lbl_do_expr, - lbl_skip_expr))] + c = IRBlock(loc_do, [AssignBlock(e_do, instr)]) + e_n = [m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_reg, loc_do_expr, + loc_skip_expr))] return e_n, [cond_bloc, c] + new_extra_ir def expr_fix_regs_for_mode(self, e, mode=64): @@ -5208,7 +5209,7 @@ class ir_x86_16(IntermediateRepresentation): src = self.expr_fix_regs_for_mode(src, mode) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, assignblk.instr)) - return IRBlock(irblock.label, irs) + return IRBlock(irblock.loc_key, irs) class ir_x86_32(ir_x86_16): diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py index 9764590a..1f54a7e4 100644 --- a/miasm2/core/asmblock.py +++ b/miasm2/core/asmblock.py @@ -5,8 +5,7 @@ import warnings from collections import namedtuple from miasm2.expression.expression import ExprId, ExprInt, ExprLoc, \ - get_expr_labels -from miasm2.core.asmblock import AsmSymbolPool + get_expr_locs from miasm2.expression.expression import LocKey from miasm2.expression.simplifications import expr_simp from miasm2.expression.modint import moduint, modint @@ -27,42 +26,6 @@ def is_int(a): isinstance(a, moduint) or isinstance(a, modint) -class AsmLabel(object): - - "Stand for an assembly label" - - def __init__(self, loc_key, name="", offset=None): - assert isinstance(loc_key, LocKey) - self.loc_key = loc_key - self.fixedblocs = False - if is_int(name): - name = "loc_%.16X" % (int(name) & 0xFFFFFFFFFFFFFFFF) - self.name = name - self.attrib = None - if offset is None: - self.offset = None - else: - self.offset = int(offset) - - def __str__(self): - if isinstance(self.offset, (int, long)): - return "%s:0x%08x" % (self.name, self.offset) - else: - return "%s:%s" % (self.name, str(self.offset)) - - def __repr__(self): - rep = '<%s ' % self.__class__.__name__ - if self.name: - rep += repr(self.name) + ' ' - rep += '>' - return rep - - -class asm_label(AsmLabel): - - def __init__(self, name="", offset=None): - warnings.warn('DEPRECATION WARNING: use "AsmLabel" instead of "asm_label"') - super(asm_label, self).__init__(name, offset) class AsmRaw(object): @@ -87,63 +50,86 @@ class AsmConstraint(object): c_to = "c_to" c_next = "c_next" - def __init__(self, label, c_t=c_to): + def __init__(self, loc_key, c_t=c_to): # Sanity check - assert isinstance(label, AsmLabel) + assert isinstance(loc_key, LocKey) - self.label = label + self.loc_key = loc_key self.c_t = c_t + def get_label(self): + warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') + return self.loc_key + + def set_label(self, loc_key): + warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') + self.loc_key = loc_key + + label = property(get_label, set_label) + def __str__(self): - return "%s:%s" % (str(self.c_t), str(self.label)) + return "%s:%s" % (str(self.c_t), str(self.loc_key)) class asm_constraint(AsmConstraint): - def __init__(self, label, c_t=AsmConstraint.c_to): + def __init__(self, loc_key, c_t=AsmConstraint.c_to): warnings.warn('DEPRECATION WARNING: use "AsmConstraint" instead of "asm_constraint"') - super(asm_constraint, self).__init__(label, c_t) + super(asm_constraint, self).__init__(loc_key, c_t) class AsmConstraintNext(AsmConstraint): - def __init__(self, label): + def __init__(self, loc_key): super(AsmConstraintNext, self).__init__( - label, c_t=AsmConstraint.c_next) + loc_key, + c_t=AsmConstraint.c_next + ) class asm_constraint_next(AsmConstraint): - def __init__(self, label): + def __init__(self, loc_key): warnings.warn('DEPRECATION WARNING: use "AsmConstraintNext" instead of "asm_constraint_next"') - super(asm_constraint_next, self).__init__(label) + super(asm_constraint_next, self).__init__(loc_key) class AsmConstraintTo(AsmConstraint): - def __init__(self, label): + def __init__(self, loc_key): super(AsmConstraintTo, self).__init__( - label, c_t=AsmConstraint.c_to) + loc_key, + c_t=AsmConstraint.c_to + ) class asm_constraint_to(AsmConstraint): - def __init__(self, label): + def __init__(self, loc_key): warnings.warn('DEPRECATION WARNING: use "AsmConstraintTo" instead of "asm_constraint_to"') - super(asm_constraint_to, self).__init__(label) + super(asm_constraint_to, self).__init__(loc_key) class AsmBlock(object): - def __init__(self, label, alignment=1): - assert isinstance(label, AsmLabel) + def __init__(self, loc_key, alignment=1): + assert isinstance(loc_key, LocKey) + self.bto = set() self.lines = [] - self.label = label + self._loc_key = loc_key self.alignment = alignment + def get_label(self): + warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') + return self.loc_key + + loc_key = property(lambda self:self._loc_key) + label = property(get_label) + + def __str__(self): out = [] - out.append(str(self.label)) + out.append(str(self.loc_key)) for l in self.lines: out.append(str(l)) if self.bto: @@ -164,23 +150,25 @@ class AsmBlock(object): assert isinstance(self.bto, set) self.bto.add(c) - def split(self, offset, l): + def split(self, symbol_pool, offset): + loc_key = symbol_pool.getby_offset_create(offset) log_asmblock.debug('split at %x', offset) i = -1 offsets = [x.offset for x in self.lines] - if not l.offset in offsets: + offset = symbol_pool.loc_key_to_offset(loc_key) + if offset not in offsets: log_asmblock.warning( 'cannot split bloc at %X ' % offset + 'middle instruction? default middle') offsets.sort() return None - new_bloc = AsmBlock(l) + new_bloc = AsmBlock(loc_key) i = offsets.index(offset) self.lines, new_bloc.lines = self.lines[:i], self.lines[i:] flow_mod_instr = self.get_flow_instr() log_asmblock.debug('flow mod %r', flow_mod_instr) - c = AsmConstraint(l, AsmConstraint.c_next) + c = AsmConstraint(loc_key, AsmConstraint.c_next) # move dst if flowgraph modifier was in original bloc # (usecase: split delayslot bloc) if flow_mod_instr: @@ -207,16 +195,9 @@ class AsmBlock(object): def get_offsets(self): return [x.offset for x in self.lines] - def add_cst(self, offset, c_t, symbol_pool): - if isinstance(offset, (int, long)): - l = symbol_pool.getby_offset_create(offset) - elif isinstance(offset, str): - l = symbol_pool.getby_name_create(offset) - elif isinstance(offset, AsmLabel): - l = offset - else: - raise ValueError('unknown offset type %r' % offset) - c = AsmConstraint(l, c_t) + def add_cst(self, loc_key, c_t, symbol_pool): + assert isinstance(loc_key, LocKey) + c = AsmConstraint(loc_key, c_t) self.bto.add(c) def get_flow_instr(self): @@ -242,9 +223,9 @@ class AsmBlock(object): return None def get_next(self): - for x in self.bto: - if x.c_t == AsmConstraint.c_next: - return x.label + for constraint in self.bto: + if constraint.c_t == AsmConstraint.c_next: + return constraint.loc_key return None @staticmethod @@ -277,7 +258,7 @@ class AsmBlock(object): # destination -> associated constraints dests = {} for constraint in self.bto: - dests.setdefault(constraint.label, set()).add(constraint) + dests.setdefault(constraint.loc_key, set()).add(constraint) self.bto = set(self._filter_constraint(constraints) for constraints in dests.itervalues()) @@ -285,9 +266,9 @@ class AsmBlock(object): class asm_bloc(object): - def __init__(self, label, alignment=1): + def __init__(self, loc_key, alignment=1): warnings.warn('DEPRECATION WARNING: use "AsmBlock" instead of "asm_bloc"') - super(asm_bloc, self).__init__(label, alignment) + super(asm_bloc, self).__init__(loc_key, alignment) class AsmBlockBad(AsmBlock): @@ -311,19 +292,19 @@ class AsmBlockBad(AsmBlock): ERROR_IO: "IOError", } - def __init__(self, label=None, alignment=1, errno=ERROR_UNKNOWN, *args, **kwargs): + def __init__(self, loc_key=None, alignment=1, errno=ERROR_UNKNOWN, *args, **kwargs): """Instanciate an AsmBlock_bad. - @label, @alignement: same as AsmBlock.__init__ + @loc_key, @alignement: same as AsmBlock.__init__ @errno: (optional) specify a error type associated with the block """ - super(AsmBlockBad, self).__init__(label, alignment, *args, **kwargs) + super(AsmBlockBad, self).__init__(loc_key, alignment, *args, **kwargs) self._errno = errno errno = property(lambda self: self._errno) def __str__(self): error_txt = self.ERROR_TYPES.get(self._errno, self._errno) - return "\n".join([str(self.label), + return "\n".join([str(self.loc_key), "\tBad block: %s" % error_txt]) def addline(self, *args, **kwargs): @@ -338,9 +319,9 @@ class AsmBlockBad(AsmBlock): class asm_block_bad(AsmBlockBad): - def __init__(self, label=None, alignment=1, errno=-1, *args, **kwargs): + def __init__(self, loc_key=None, alignment=1, errno=-1, *args, **kwargs): warnings.warn('DEPRECATION WARNING: use "AsmBlockBad" instead of "asm_block_bad"') - super(asm_block_bad, self).__init__(label, alignment, *args, **kwargs) + super(asm_block_bad, self).__init__(loc_key, alignment, *args, **kwargs) class AsmSymbolPool(object): @@ -357,134 +338,182 @@ class AsmSymbolPool(object): """ def __init__(self): - self._labels = set() - self._name2label = {} - self._offset2label = {} - self._label_num = 0 - self._loc_key_to_label = {} + self._loc_keys = set() + + self._loc_key_to_offset = {} + self._loc_key_to_name = {} + + self._name_to_loc_key = {} + self._offset_to_loc_key = {} - def loc_key_to_label(self, label_index): - assert isinstance(label_index, LocKey) - return self._loc_key_to_label.get(label_index.key, None) + self._loc_key_num = 0 - def add_label(self, name, offset=None): + def loc_key_to_offset(self, loc_key): """ - Create and add a label to the symbol_pool - @name: label's name - @offset: (optional) label's offset + Return offset of @loc_key, None otherwise. + @loc_key: LocKey instance """ - label = AsmLabel(LocKey(self._label_num), name, offset) + return self._loc_key_to_offset.get(loc_key) + + def loc_key_to_name(self, loc_key): + """ + Return name of @loc_key. + @loc_key: LocKey instance + """ + return self._loc_key_to_name[loc_key] + + def add_location(self, name, offset=None): + """ + Create and add a location to the symbol_pool + @name: loc_key's name (never empty). If offset is None and name is int, + generate loc_key with generic name and name as offset + @offset: (optional) loc_key's offset + """ + + if is_int(name): + assert offset is None or offset == name + offset = name + name = "loc_%.16X" % (int(name) & 0xFFFFFFFFFFFFFFFF) + if offset is not None: + offset = int(offset) + + assert name # Test for collisions - if (label.offset in self._offset2label and - label != self._offset2label[label.offset]): - raise ValueError('symbol %s has same offset as %s' % - (label, self._offset2label[label.offset])) - if (label.name in self._name2label and - label != self._name2label[label.name]): - raise ValueError('symbol %s has same name as %s' % - (label, self._name2label[label.name])) - - self._labels.add(label) - self._label_num += 1 - self._loc_key_to_label[label.loc_key.key] = label - - if label.offset is not None: - self._offset2label[label.offset] = label - if label.name != "": - self._name2label[label.name] = label - return label - - def remove_label(self, label): + known_loc_key = self.getby_name(name) + if known_loc_key is not None: + known_offset = self.loc_key_to_offset(known_loc_key) + if known_offset != offset: + raise ValueError( + 'symbol %s with different offset %s %s' % ( + name, offset, known_offset + ) + ) + return known_loc_key + + elif self.getby_offset(offset) is not None: + raise ValueError( + 'offset %s with different names %s' % ( + offset, + name + ) + ) + + loc_key = LocKey(self._loc_key_num) + self._loc_key_num += 1 + + self._loc_keys.add(loc_key) + + if offset is not None: + assert offset not in self._offset_to_loc_key + self._offset_to_loc_key[offset] = loc_key + self._loc_key_to_offset[loc_key] = offset + + self._name_to_loc_key[name] = loc_key + self._loc_key_to_name[loc_key] = name + return loc_key + + def remove_loc_key(self, loc_key): """ - Delete a @label + Delete a @loc_key """ - self._name2label.pop(label.name, None) - self._offset2label.pop(label.offset, None) - if label in self._labels: - self._labels.remove(label) + name = self._loc_key_to_name.pop(loc_key, None) + self._name_to_loc_key.pop(name, None) + + offset = self._loc_key_to_offset.pop(loc_key, None) + self._offset_to_loc_key.pop(offset, None) + + self._loc_keys.remove(loc_key) - def del_label_offset(self, label): - """Unpin the @label from its offset""" - self._offset2label.pop(label.offset, None) - label.offset = None + def del_loc_key_offset(self, loc_key): + """Unpin the @loc_key from its offset""" + offset = self._loc_keys_to_offset.pop(loc_key) + self._offset_to_loc_key.pop(offset, None) def getby_offset(self, offset): - """Retrieve label using its @offset""" - return self._offset2label.get(offset, None) + """ + Retrieve loc_key using its @offset, None otherwise. + @offset: int + """ + return self._offset_to_loc_key.get(offset) def getby_name(self, name): - """Retrieve label using its @name""" - return self._name2label.get(name, None) + """ + Retrieve loc_key using its @name, None otherwise. + @name: str + """ + return self._name_to_loc_key.get(name) def getby_name_create(self, name): - """Get a label from its @name, create it if it doesn't exist""" - label = self.getby_name(name) - if label is None: - label = self.add_label(name) - return label + """Get a loc_key from its @name, create it if it doesn't exist""" + loc_key = self.getby_name(name) + if loc_key is None: + loc_key = self.add_location(name) + return loc_key def getby_offset_create(self, offset): - """Get a label from its @offset, create it if it doesn't exist""" - label = self.getby_offset(offset) - if label is None: - label = self.add_label(offset, offset) - return label - - def rename_label(self, label, newname): - """Rename the @label name to @newname""" - if newname in self._name2label: + """Get a loc_key from its @offset, create it if it doesn't exist""" + loc_key = self.getby_offset(offset) + if loc_key is None: + loc_key = self.add_location(offset) + return loc_key + + def rename_location(self, loc_key, newname): + """Rename the @loc_key name to @newname""" + if newname in self._name_to_loc_key: raise ValueError('Symbol already known') - self._name2label.pop(label.name, None) - label.name = newname - self._name2label[label.name] = label + name = self._loc_key_to_name[loc_key] + assert name is not None + self._name_to_loc_key.pop(name) + self._loc_key_to_name[loc_key] = newname - def set_offset(self, label, offset): - """Pin the @label from at @offset + def set_offset(self, loc_key, offset): + """Pin the @loc_key to an @offset Note that there is a special case when the offset is a list it happens when offsets are recomputed in resolve_symbol* """ - if label is None: - raise ValueError('label should not be None') - if not label.name in self._name2label: - raise ValueError('label %s not in symbol pool' % label) - if offset is not None and offset in self._offset2label: - raise ValueError('Conflict in label %s' % label) - self._offset2label.pop(label.offset, None) - label.offset = offset - if is_int(label.offset): - self._offset2label[label.offset] = label + assert isinstance(loc_key, LocKey) + assert offset not in self._offset_to_loc_key + if loc_key not in self._loc_keys: + raise ValueError('Foreign loc_key %s' % loc_key) + + old_offset = self._loc_key_to_offset.pop(loc_key, None) + self._offset_to_loc_key.pop(old_offset, None) + + self._loc_key_to_offset[loc_key] = offset + self._offset_to_loc_key[offset] = loc_key @property - def labels(self): - """Return all labels""" - return self._labels + def loc_keys(self): + """Return all loc_keys""" + return self._loc_keys @property def items(self): - """Return all labels""" - warnings.warn('DEPRECATION WARNING: use "labels" instead of "items"') - return list(self._labels) - + """Return all loc_keys""" + warnings.warn('DEPRECATION WARNING: use "loc_keys" instead of "items"') + return list(self._loc_keys) def __str__(self): - return reduce(lambda x, y: x + str(y) + '\n', self._labels, "") + return "".join("%s\n" % loc_key for loc_key in self._loc_keys) def __getitem__(self, item): - if item in self._name2label: - return self._name2label[item] - if item in self._offset2label: - return self._offset2label[item] + warnings.warn('DEPRECATION WARNING: use "offset_to_loc_key" or "name_to_loc_key"') + if item in self._name_to_loc_key: + return self._name_to_loc_key[item] + if item in self._offset_to_loc_key: + return self._offset_to_loc_key[item] raise KeyError('unknown symbol %r' % item) def __contains__(self, item): - return item in self._name2label or item in self._offset2label + warnings.warn('DEPRECATION WARNING: use "offset_to_loc_key" or "name_to_loc_key"') + return item in self._name_to_loc_key or item in self._offset_to_loc_key def merge(self, symbol_pool): """Merge with another @symbol_pool""" - self._labels.update(symbol_pool.labels) - self._name2label.update(symbol_pool._name2label) - self._offset2label.update(symbol_pool._offset2label) + self._loc_keys.update(symbol_pool.loc_keys) + self._name_to_loc_key.update(symbol_pool._name_to_loc_key) + self._offset_to_loc_key.update(symbol_pool._offset_to_loc_key) def canonize_to_exprloc(self, expr): """ @@ -494,16 +523,27 @@ class AsmSymbolPool(object): @expr: Expr instance """ if expr.is_int(): - label = self.getby_offset_create(int(expr)) - ret = ExprLoc(label.loc_key, expr.size) + loc_key = self.getby_offset_create(int(expr)) + ret = ExprLoc(loc_key, expr.size) return ret return expr - def gen_label(self): - """Generate a new unpinned label""" - label = self.add_label("lbl_gen_%.8X" % (self._label_num)) - self._label_num += 1 - return label + def gen_loc_key(self): + """Generate a new unpinned loc_key""" + loc_key = self.add_location("lbl_gen_%.8X" % (self._loc_key_num)) + return loc_key + + def str_loc_key(self, loc_key): + name = self.loc_key_to_name(loc_key) + offset = self.loc_key_to_offset(loc_key) + if name is None: + name = str(loc_key) + if offset is not None: + offset = hex(offset) + out = name + if offset is not None: + out = "%s:%s" % (out, offset) + return out class asm_symbol_pool(AsmSymbolPool): @@ -522,7 +562,7 @@ class AsmCFG(DiGraph): Specialized the .dot export and force the relation between block to be uniq, and associated with a constraint. - Offer helpers on AsmCFG management, such as research by label, sanity + Offer helpers on AsmCFG management, such as research by loc_key, sanity checking and mnemonic size guessing. """ @@ -531,15 +571,13 @@ class AsmCFG(DiGraph): ["waiter", "constraint"]) def __init__(self, symbol_pool=None, *args, **kwargs): - if symbol_pool is None: - raise DeprecationWarning("AsmCFG needs a non empty symbol_pool") super(AsmCFG, self).__init__(*args, **kwargs) # Edges -> constraint self.edges2constraint = {} - # Expected AsmLabel -> set( (src, dst), constraint ) + # Expected LocKey -> set( (src, dst), constraint ) self._pendings = {} - # Label2block built on the fly - self._label2block = {} + # Loc_Key2block built on the fly + self._loc_key_to_block = {} # symbol_pool self.symbol_pool = symbol_pool @@ -560,112 +598,163 @@ class AsmCFG(DiGraph): def __getitem__(self, *args, **kwargs): raise DeprecationWarning("Order of AsmCFG elements is not reliable") + def __contains__(self, _): + """ + DEPRECATED. Use: + - loc_key in AsmCFG.nodes() to test loc_key existence + """ + raise RuntimeError("DEPRECATED") + def __iter__(self): - """Iterator on AsmBlock composing the current graph""" - return iter(self._nodes) + """ + DEPRECATED. Use: + - AsmCFG.blocks() to iter on blocks + - loc_key in AsmCFG.nodes() to test loc_key existence + """ + raise RuntimeError("DEPRECATED") def __len__(self): """Return the number of blocks in AsmCFG""" return len(self._nodes) + blocks = property(lambda x:x._loc_key_to_block.itervalues()) + # Manage graph with associated constraints def add_edge(self, src, dst, constraint): """Add an edge to the graph - @src: AsmBlock instance, source - @dst: AsmBlock instance, destination + @src: LocKey instance, source + @dst: LocKey instance, destination @constraint: constraint associated to this edge """ # Sanity check - assert (src, dst) not in self.edges2constraint + assert isinstance(src, LocKey) + assert isinstance(dst, LocKey) + known_cst = self.edges2constraint.get((src, dst), None) + if known_cst is not None: + assert known_cst == constraint + return # Add the edge to src.bto if needed - if dst.label not in [cons.label for cons in src.bto]: - src.bto.add(AsmConstraint(dst.label, constraint)) + block_src = self.loc_key_to_block(src) + if block_src: + if dst not in [cons.loc_key for cons in block_src.bto]: + block_src.bto.add(AsmConstraint(dst, constraint)) # Add edge self.edges2constraint[(src, dst)] = constraint super(AsmCFG, self).add_edge(src, dst) def add_uniq_edge(self, src, dst, constraint): - """Add an edge from @src to @dst if it doesn't already exist""" + """ + Add an edge from @src to @dst if it doesn't already exist + @src: LocKey instance, source + @dst: LocKey instance, destination + @constraint: constraint associated to this edge + """ if (src not in self._nodes_succ or dst not in self._nodes_succ[src]): self.add_edge(src, dst, constraint) def del_edge(self, src, dst): """Delete the edge @src->@dst and its associated constraint""" + src_blk = self.loc_key_to_block(src) + dst_blk = self.loc_key_to_block(dst) + assert src_blk is not None + assert dst_blk is not None # Delete from src.bto - to_remove = [cons for cons in src.bto if cons.label == dst.label] + to_remove = [cons for cons in src_blk.bto if cons.loc_key == dst] if to_remove: assert len(to_remove) == 1 - src.bto.remove(to_remove[0]) + src_blk.bto.remove(to_remove[0]) # Del edge del self.edges2constraint[(src, dst)] super(AsmCFG, self).del_edge(src, dst) - def add_node(self, block): - """Add the block @block to the current instance, if it is not already in + def del_block(self, block): + super(AsmCFG, self).del_node(block.loc_key) + del self._loc_key_to_block[block.loc_key] + + + def add_node(self, node): + assert isinstance(node, LocKey) + return super(AsmCFG, self).add_node(node) + + def add_block(self, block): + """ + Add the block @block to the current instance, if it is not already in @block: AsmBlock instance Edges will be created for @block.bto, if destinations are already in this instance. If not, they will be resolved when adding these aforementionned destinations. `self.pendings` indicates which blocks are not yet resolved. + """ - status = super(AsmCFG, self).add_node(block) + status = super(AsmCFG, self).add_node(block.loc_key) + if not status: return status # Update waiters - if block.label in self._pendings: - for bblpend in self._pendings[block.label]: - self.add_edge(bblpend.waiter, block, bblpend.constraint) - del self._pendings[block.label] + if block.loc_key in self._pendings: + for bblpend in self._pendings[block.loc_key]: + self.add_edge(bblpend.waiter.loc_key, block.loc_key, bblpend.constraint) + del self._pendings[block.loc_key] # Synchronize edges with block destinations - self._label2block[block.label] = block + self._loc_key_to_block[block.loc_key] = block + for constraint in block.bto: - dst = self._label2block.get(constraint.label, - None) + dst = self._loc_key_to_block.get(constraint.loc_key, + None) if dst is None: # Block is yet unknown, add it to pendings to_add = self.AsmCFGPending(waiter=block, constraint=constraint.c_t) - self._pendings.setdefault(constraint.label, + self._pendings.setdefault(constraint.loc_key, set()).add(to_add) else: # Block is already in known nodes - self.add_edge(block, dst, constraint.c_t) + self.add_edge(block.loc_key, dst.loc_key, constraint.c_t) return status - def del_node(self, block): - super(AsmCFG, self).del_node(block) - del self._label2block[block.label] - def merge(self, graph): """Merge with @graph, taking in account constraints""" # -> add_edge(x, y, constraint) - for node in graph._nodes: - self.add_node(node) + self._loc_key_to_block.update(graph._loc_key_to_block) + for loc_key in graph._nodes: + self.add_node(loc_key) + if loc_key in graph._loc_key_to_block: + self.add_block(graph._loc_key_to_block[loc_key]) for edge in graph._edges: # Use "_uniq_" beacause the edge can already exist due to add_node - self.add_uniq_edge(*edge, constraint=graph.edges2constraint[edge]) + self.add_edge(*edge, constraint=graph.edges2constraint[edge]) + def node2lines(self, node): - yield self.DotCellDescription(text=str(node.label.name), + if self.symbol_pool is None: + loc_key_name = str(node) + else: + loc_key_name = self.symbol_pool.str_loc_key(node) + yield self.DotCellDescription(text=loc_key_name, attr={'align': 'center', 'colspan': 2, 'bgcolor': 'grey'}) - - if isinstance(node, AsmBlockBad): - yield [self.DotCellDescription( - text=node.ERROR_TYPES.get(node._errno, - node._errno), - attr={})] + block = self._loc_key_to_block.get(node, None) + if block is None: raise StopIteration - for line in node.lines: + if isinstance(block, AsmBlockBad): + yield [ + self.DotCellDescription( + text=block.ERROR_TYPES.get(block._errno, + block._errno + ), + attr={}) + ] + raise StopIteration + for line in block.lines: if self._dot_offset: yield [self.DotCellDescription(text="%.8X" % line.offset, attr={}), @@ -674,7 +763,8 @@ class AsmCFG(DiGraph): yield self.DotCellDescription(text=line.to_string(self.symbol_pool), attr={}) def node_attr(self, node): - if isinstance(node, AsmBlockBad): + block = self._loc_key_to_block.get(node, None) + if isinstance(block, AsmBlockBad): return {'style': 'filled', 'fillcolor': 'red'} return {} @@ -700,22 +790,19 @@ class AsmCFG(DiGraph): # Helpers @property def pendings(self): - """Dictionary of label -> set(AsmCFGPending instance) indicating - which label are missing in the current instance. - A label is missing if a block which is already in nodes has constraints + """Dictionary of loc_key -> set(AsmCFGPending instance) indicating + which loc_key are missing in the current instance. + A loc_key is missing if a block which is already in nodes has constraints with him (thanks to its .bto) and the corresponding block is not yet in nodes """ return self._pendings - def _build_label2block(self): - self._label2block = {block.label: block - for block in self._nodes} - - def label2block(self, label): - """Return the block corresponding to label @label - @label: AsmLabel instance or ExprId(AsmLabel) instance""" - return self._label2block[label] + def label2block(self, loc_key): + """Return the block corresponding to loc_key @loc_key + @loc_key: LocKey instance""" + warnings.warn('DEPRECATION WARNING: use "loc_key_to_block" instead of "label2block"') + return self.loc_key_to_block(loc_key) def rebuild_edges(self): """Consider blocks '.bto' and rebuild edges according to them, ie: @@ -726,20 +813,25 @@ class AsmCFG(DiGraph): This method should be called if a block's '.bto' in nodes have been modified without notifying this instance to resynchronize edges. """ - self._build_label2block() - for block in self._nodes: + for block in self.blocks: edges = [] # Rebuild edges from bto for constraint in block.bto: - dst = self._label2block.get(constraint.label, - None) + dst = self._loc_key_to_block.get(constraint.loc_key, + None) if dst is None: # Missing destination, add to pendings - self._pendings.setdefault(constraint.label, - set()).add(self.AsmCFGPending(block, - constraint.c_t)) + self._pendings.setdefault( + constraint.loc_key, + set() + ).add( + self.AsmCFGPending( + block, + constraint.c_t + ) + ) continue - edge = (block, dst) + edge = (block.loc_key, dst.loc_key) edges.append(edge) if edge in self._edges: # Already known edge, constraint may have changed @@ -749,43 +841,52 @@ class AsmCFG(DiGraph): self.add_edge(edge[0], edge[1], constraint.c_t) # Remove useless edges - for succ in self.successors(block): - edge = (block, succ) + for succ in self.successors(block.loc_key): + edge = (block.loc_key, succ) if edge not in edges: self.del_edge(*edge) def get_bad_blocks(self): """Iterator on AsmBlockBad elements""" # A bad asm block is always a leaf - for block in self.leaves(): + for loc_key in self.leaves(): + block = self._loc_key_to_block.get(loc_key, None) if isinstance(block, AsmBlockBad): yield block def get_bad_blocks_predecessors(self, strict=False): - """Iterator on block with an AsmBlockBad destination - @strict: (optional) if set, return block with only bad + """Iterator on loc_keys with an AsmBlockBad destination + @strict: (optional) if set, return loc_key with only bad successors """ # Avoid returning the same block done = set() for badblock in self.get_bad_blocks(): - for predecessor in self.predecessors_iter(badblock): + for predecessor in self.predecessors_iter(badblock.loc_key): if predecessor not in done: if (strict and - not all(isinstance(block, AsmBlockBad) + not all(isinstance(self._loc_key_to_block.get(block, None), AsmBlockBad) for block in self.successors_iter(predecessor))): continue yield predecessor done.add(predecessor) def getby_offset(self, offset): - """Return block containing @offset""" - for block in self: + """Return asmblock containing @offset""" + for block in self.blocks: if block.lines[0].offset <= offset < \ (block.lines[-1].offset + block.lines[-1].l): return block return None + def loc_key_to_block(self, loc_key): + """ + Return the asmblock corresponding to loc_key @loc_key, None if unknown + loc_key + @loc_key: LocKey instance + """ + return self._loc_key_to_block.get(loc_key, None) + def sanity_check(self): """Do sanity checks on blocks' constraints: * no pendings @@ -794,33 +895,37 @@ class AsmCFG(DiGraph): """ if len(self._pendings) != 0: - raise RuntimeError("Some blocks are missing: %s" % map(str, - self._pendings.keys())) + raise RuntimeError("Some blocks are missing: %s" % map( + str, + self._pendings.keys() + )) next_edges = {edge: constraint for edge, constraint in self.edges2constraint.iteritems() if constraint == AsmConstraint.c_next} - for block in self._nodes: + for loc_key in self._nodes: + if loc_key not in self._loc_key_to_block: + raise RuntimeError("Not supported yet: every node must have a corresponding AsmBlock") # No next constraint to self - if (block, block) in next_edges: + if (loc_key, loc_key) in next_edges: raise RuntimeError('Bad constraint: self in next') # No multiple next constraint to same block - pred_next = list(pblock - for (pblock, dblock) in next_edges - if dblock == block) + pred_next = list(ploc_key + for (ploc_key, dloc_key) in next_edges + if dloc_key == loc_key) if len(pred_next) > 1: raise RuntimeError("Too many next constraints for bloc %r" - "(%s)" % (block.label, - [x.label for x in pred_next])) + "(%s)" % (loc_key, + pred_next)) def guess_blocks_size(self, mnemo): """Asm and compute max block size Add a 'size' and 'max_size' attribute on each block @mnemo: metamn instance""" - for block in self._nodes: + for block in self.blocks: size = 0 for instr in block.lines: if isinstance(instr, AsmRaw): @@ -857,21 +962,23 @@ class AsmCFG(DiGraph): def apply_splitting(self, symbol_pool, dis_block_callback=None, **kwargs): """Consider @self' bto destinations and split block in @self if one of these destinations jumps in the middle of this block. - In order to work, they must be only one block in @self per label in + In order to work, they must be only one block in @self per loc_key in @symbol_pool (which is true if @self come from the same disasmEngine). - @symbol_pool: AsmSymbolPool instance associated with @self'labels + @symbol_pool: AsmSymbolPool instance associated with @self'loc_keys @dis_block_callback: (optional) if set, this callback will be called on new block destinations @kwargs: (optional) named arguments to pass to dis_block_callback """ # Get all possible destinations not yet resolved, with a resolved # offset - block_dst = [label.offset - for label in self.pendings - if label.offset is not None] + block_dst = [] + for loc_key in self.pendings: + offset = symbol_pool.loc_key_to_offset(loc_key) + if offset is not None: + block_dst.append(offset) - todo = self.nodes().copy() + todo = set(self.blocks) rebuild_needed = False while todo: @@ -884,8 +991,7 @@ class AsmCFG(DiGraph): continue # `cur_block` must be splitted at offset `off` - label = symbol_pool.getby_offset_create(off) - new_b = cur_block.split(off, label) + new_b = cur_block.split(symbol_pool, off) log_asmblock.debug("Split block %x", off) if new_b is None: log_asmblock.error("Cannot split %x!!", off) @@ -894,22 +1000,24 @@ class AsmCFG(DiGraph): # Remove pending from cur_block # Links from new_b will be generated in rebuild_edges for dst in new_b.bto: - if dst.label not in self.pendings: + if dst.loc_key not in self.pendings: continue - self.pendings[dst.label] = set(pending for pending in self.pendings[dst.label] - if pending.waiter != cur_block) + self.pendings[dst.loc_key] = set(pending for pending in self.pendings[dst.loc_key] + if pending.waiter != cur_block) # The new block destinations may need to be disassembled if dis_block_callback: - offsets_to_dis = set(constraint.label.offset - for constraint in new_b.bto) + offsets_to_dis = set( + self.symbol_pool.loc_key_to_offset(constraint.loc_key) + for constraint in new_b.bto + ) dis_block_callback(cur_bloc=new_b, offsets_to_dis=offsets_to_dis, symbol_pool=symbol_pool, **kwargs) # Update structure rebuild_needed = True - self.add_node(new_b) + self.add_block(new_b) # The new block must be considered todo.add(new_b) @@ -921,18 +1029,18 @@ class AsmCFG(DiGraph): def __str__(self): out = [] - for node in self.nodes(): - out.append(str(node)) - for nodeA, nodeB in self.edges(): - out.append("%s -> %s" % (nodeA.label, nodeB.label)) + for block in self.blocks: + out.append(str(block)) + for loc_key_a, loc_key_b in self.edges(): + out.append("%s -> %s" % (loc_key_a, loc_key_b)) return '\n'.join(out) def __repr__(self): return "<%s %s>" % (self.__class__.__name__, hex(id(self))) # Out of _merge_blocks to be computed only once -_acceptable_block = lambda block: (not isinstance(block, AsmBlockBad) and - len(block.lines) > 0) +_acceptable_block = lambda graph, loc_key: (not isinstance(graph.loc_key_to_block(loc_key), AsmBlockBad) and + len(graph.loc_key_to_block(loc_key).lines) > 0) _parent = MatchGraphJoker(restrict_in=False, filt=_acceptable_block) _son = MatchGraphJoker(restrict_out=False, filt=_acceptable_block) _expgraph = _parent >> _son @@ -948,7 +1056,9 @@ def _merge_blocks(dg, graph): for match in _expgraph.match(graph): # Get matching blocks - block, succ = match[_parent], match[_son] + lbl_block, lbl_succ = match[_parent], match[_son] + block = graph.loc_key_to_block(lbl_block) + succ = graph.loc_key_to_block(lbl_succ) # Ignore already deleted blocks if (block in to_ignore or @@ -968,11 +1078,11 @@ def _merge_blocks(dg, graph): # Merge block block.lines += succ.lines - for nextb in graph.successors_iter(succ): - graph.add_edge(block, nextb, graph.edges2constraint[(succ, nextb)]) + for nextb in graph.successors_iter(lbl_succ): + graph.add_edge(lbl_block, nextb, graph.edges2constraint[(lbl_succ, nextb)]) - graph.del_node(succ) - to_ignore.add(succ) + graph.del_block(succ) + to_ignore.add(lbl_succ) bbl_simplifier = DiGraphSimplifier() @@ -1002,8 +1112,12 @@ def fix_expr_val(expr, symbols): """Resolve an expression @expr using @symbols""" def expr_calc(e): if isinstance(e, ExprId): - s = symbols._name2label[e.name] - e = ExprInt(s.offset, e.size) + # Example: + # toto: + # .dword label + loc_key = symbols.getby_name(e.name) + offset = symbols.loc_key_to_offset(loc_key) + e = ExprInt(offset, e.size) return e result = expr.visit(expr_calc) result = expr_simp(result) @@ -1012,15 +1126,17 @@ def fix_expr_val(expr, symbols): return result -def fix_label_offset(symbol_pool, label, offset, modified): - """Fix the @label offset to @offset. If the @offset has changed, add @label +def fix_loc_offset(symbol_pool, loc_key, offset, modified): + """ + Fix the @loc_key offset to @offset. If the @offset has changed, add @loc_key to @modified @symbol_pool: current symbol_pool """ - if label.offset == offset: + loc_offset = symbol_pool.loc_key_to_offset(loc_key) + if loc_offset == offset: return - symbol_pool.set_offset(label, offset) - modified.add(label) + symbol_pool.set_offset(loc_key, offset) + modified.add(loc_key) class BlockChain(object): @@ -1040,7 +1156,8 @@ class BlockChain(object): def _set_pinned_block_idx(self): self.pinned_block_idx = None for i, block in enumerate(self.blocks): - if is_int(block.label.offset): + loc_key = block.loc_key + if self.symbol_pool.loc_key_to_offset(loc_key) is not None: if self.pinned_block_idx is not None: raise ValueError("Multiples pinned block detected") self.pinned_block_idx = i @@ -1058,7 +1175,8 @@ class BlockChain(object): if not self.pinned: return - offset_base = self.blocks[self.pinned_block_idx].label.offset + loc = self.blocks[self.pinned_block_idx].loc_key + offset_base = self.symbol_pool.loc_key_to_offset(loc) assert(offset_base % self.blocks[self.pinned_block_idx].alignment == 0) self.offset_min = offset_base @@ -1078,40 +1196,40 @@ class BlockChain(object): self.place() return [self] - def fix_blocks(self, modified_labels): + def fix_blocks(self, modified_loc_keys): """Propagate a pinned to its blocks' neighbour - @modified_labels: store new pinned labels""" + @modified_loc_keys: store new pinned loc_keys""" if not self.pinned: raise ValueError('Trying to fix unpinned block') # Propagate offset to blocks before pinned block pinned_block = self.blocks[self.pinned_block_idx] - offset = pinned_block.label.offset + offset = self.symbol_pool.loc_key_to_offset(pinned_block.loc_key) if offset % pinned_block.alignment != 0: raise RuntimeError('Bad alignment') for block in self.blocks[:self.pinned_block_idx - 1:-1]: new_offset = offset - block.size new_offset = new_offset - new_offset % pinned_block.alignment - fix_label_offset(self.symbol_pool, - block.label, - new_offset, - modified_labels) + fix_loc_offset(self.symbol_pool, + block.loc_key, + new_offset, + modified_loc_keys) # Propagate offset to blocks after pinned block - offset = pinned_block.label.offset + pinned_block.size + offset = self.symbol_pool.loc_key_to_offset(pinned_block.loc_key) + pinned_block.size last_block = pinned_block for block in self.blocks[self.pinned_block_idx + 1:]: offset += (- offset) % last_block.alignment - fix_label_offset(self.symbol_pool, - block.label, - offset, - modified_labels) + fix_loc_offset(self.symbol_pool, + block.loc_key, + offset, + modified_loc_keys) offset += block.size last_block = block - return modified_labels + return modified_loc_keys class BlockChainWedge(object): @@ -1128,23 +1246,22 @@ class BlockChainWedge(object): def merge(self, chain): """Best effort merge two block chains Return the list of resulting blockchains""" - self.symbol_pool.set_offset(chain.blocks[0].label, self.offset_max) + self.symbol_pool.set_offset(chain.blocks[0].loc_key, self.offset_max) chain.place() return [self, chain] -def group_constrained_blocks(symbol_pool, blocks): +def group_constrained_blocks(symbol_pool, asmcfg): """ - Return the BlockChains list built from grouped asm blocks linked by + Return the BlockChains list built from grouped blocks in asmcfg linked by asm_constraint_next - @blocks: a list of asm block + @asmcfg: an AsmCfg instance """ log_asmblock.info('group_constrained_blocks') - # Group adjacent blocks - remaining_blocks = list(blocks) + # Group adjacent asmcfg + remaining_blocks = list(asmcfg.blocks) known_block_chains = {} - lbl2block = {block.label: block for block in blocks} while remaining_blocks: # Create a new block chain @@ -1153,10 +1270,10 @@ def group_constrained_blocks(symbol_pool, blocks): # Find sons in remainings blocks linked with a next constraint while True: # Get next block - next_label = block_list[-1].get_next() - if next_label is None or next_label not in lbl2block: + next_loc_key = block_list[-1].get_next() + if next_loc_key is None or asmcfg.loc_key_to_block(next_loc_key) is None: break - next_block = lbl2block[next_label] + next_block = asmcfg.loc_key_to_block(next_loc_key) # Add the block at the end of the current chain if next_block not in remaining_blocks: @@ -1165,15 +1282,15 @@ def group_constrained_blocks(symbol_pool, blocks): remaining_blocks.remove(next_block) # Check if son is in a known block group - if next_label is not None and next_label in known_block_chains: - block_list += known_block_chains[next_label] - del known_block_chains[next_label] + if next_loc_key is not None and next_loc_key in known_block_chains: + block_list += known_block_chains[next_loc_key] + del known_block_chains[next_loc_key] - known_block_chains[block_list[0].label] = block_list + known_block_chains[block_list[0].loc_key] = block_list out_block_chains = [] - for label in known_block_chains: - chain = BlockChain(symbol_pool, known_block_chains[label]) + for loc_key in known_block_chains: + chain = BlockChain(symbol_pool, known_block_chains[loc_key]) out_block_chains.append(chain) return out_block_chains @@ -1240,22 +1357,17 @@ def resolve_symbol(blockChains, symbol_pool, dst_interval=None): return [chain for chain in fixed_chains if isinstance(chain, BlockChain)] -def filter_exprid_label(exprs): - """Extract labels from list of ExprId @exprs""" - return set(expr.name for expr in exprs if isinstance(expr.name, AsmLabel)) - - -def get_block_labels(block): - """Extract labels used by @block""" +def get_block_loc_keys(block): + """Extract loc_keys used by @block""" symbols = set() for instr in block.lines: if isinstance(instr, AsmRaw): if isinstance(instr.raw, list): for expr in instr.raw: - symbols.update(get_expr_labels(expr)) + symbols.update(get_expr_locs(expr)) else: for arg in instr.args: - symbols.update(get_expr_labels(arg)) + symbols.update(get_expr_locs(arg)) return symbols @@ -1281,7 +1393,7 @@ def assemble_block(mnemo, block, symbol_pool, conservative=False): # Assemble an instruction saved_args = list(instr.args) - instr.offset = block.label.offset + offset_i + instr.offset = symbol_pool.loc_key_to_offset(block.loc_key) + offset_i # Replace instruction's arguments by resolved ones instr.args = instr.resolve_args_with_symbols(symbol_pool) @@ -1304,20 +1416,19 @@ def assemble_block(mnemo, block, symbol_pool, conservative=False): offset_i += instr.l -def asmblock_final(mnemo, blocks, blockChains, symbol_pool, conservative=False): +def asmblock_final(mnemo, asmcfg, blockChains, symbol_pool, conservative=False): """Resolve and assemble @blockChains using @symbol_pool until fixed point is reached""" log_asmblock.debug("asmbloc_final") # Init structures - lbl2block = {block.label: block for block in blocks} - blocks_using_label = {} - for block in blocks: - exprlocs = get_block_labels(block) - labels = set(symbol_pool.loc_key_to_label(expr.loc_key) for expr in exprlocs) - for label in labels: - blocks_using_label.setdefault(label, set()).add(block) + blocks_using_loc_key = {} + for block in asmcfg.blocks: + exprlocs = get_block_loc_keys(block) + loc_keys = set(expr.loc_key for expr in exprlocs) + for loc_key in loc_keys: + blocks_using_loc_key.setdefault(loc_key, set()).add(block) block2chain = {} for chain in blockChains: @@ -1325,25 +1436,26 @@ def asmblock_final(mnemo, blocks, blockChains, symbol_pool, conservative=False): block2chain[block] = chain # Init worklist - blocks_to_rework = set(blocks) + blocks_to_rework = set(asmcfg.blocks) # Fix and re-assemble blocks until fixed point is reached while True: # Propagate pinned blocks into chains - modified_labels = set() + modified_loc_keys = set() for chain in blockChains: - chain.fix_blocks(modified_labels) + chain.fix_blocks(modified_loc_keys) - for label in modified_labels: + for loc_key in modified_loc_keys: # Retrive block with modified reference - if label in lbl2block: - blocks_to_rework.add(lbl2block[label]) + mod_block = asmcfg.loc_key_to_block(loc_key) + if mod_block is not None: + blocks_to_rework.add(mod_block) - # Enqueue blocks referencing a modified label - if label not in blocks_using_label: + # Enqueue blocks referencing a modified loc_key + if loc_key not in blocks_using_loc_key: continue - for block in blocks_using_label[label]: + for block in blocks_using_loc_key[loc_key]: blocks_to_rework.add(block) # No more work @@ -1362,23 +1474,26 @@ def asmbloc_final(mnemo, blocks, blockChains, symbol_pool, conservative=False): warnings.warn('DEPRECATION WARNING: use "asmblock_final" instead of "asmbloc_final"') asmblock_final(mnemo, blocks, blockChains, symbol_pool, conservative) -def asm_resolve_final(mnemo, blocks, symbol_pool, dst_interval=None): - """Resolve and assemble @blocks using @symbol_pool into interval +def asm_resolve_final(mnemo, asmcfg, symbol_pool, dst_interval=None): + """Resolve and assemble @asmcfg using @symbol_pool into interval @dst_interval""" - blocks.sanity_check() + asmcfg.sanity_check() - blocks.guess_blocks_size(mnemo) - blockChains = group_constrained_blocks(symbol_pool, blocks) + asmcfg.guess_blocks_size(mnemo) + blockChains = group_constrained_blocks(symbol_pool, asmcfg) resolved_blockChains = resolve_symbol( - blockChains, symbol_pool, dst_interval) + blockChains, + symbol_pool, + dst_interval + ) - asmblock_final(mnemo, blocks, resolved_blockChains, symbol_pool) + asmblock_final(mnemo, asmcfg, resolved_blockChains, symbol_pool) patches = {} output_interval = interval() - for block in blocks: - offset = block.label.offset + for block in asmcfg.blocks: + offset = symbol_pool.loc_key_to_offset(block.loc_key) for instr in block.lines: if not instr.data: # Empty line @@ -1481,8 +1596,8 @@ class disasmEngine(object): delayslot_count = self.arch.delayslot offsets_to_dis = set() add_next_offset = False - label = self.symbol_pool.getby_offset_create(offset) - cur_block = AsmBlock(label) + loc_key = self.symbol_pool.getby_offset_create(offset) + cur_block = AsmBlock(loc_key) log_asmblock.debug("dis at %X", int(offset)) while not in_delayslot or delayslot_count > 0: if in_delayslot: @@ -1492,17 +1607,25 @@ class disasmEngine(object): if not cur_block.lines: job_done.add(offset) # Block is empty -> bad block - cur_block = AsmBlockBad(label, errno=AsmBlockBad.ERROR_FORBIDDEN) + cur_block = AsmBlockBad(loc_key, errno=AsmBlockBad.ERROR_FORBIDDEN) else: # Block is not empty, stop the desassembly pass and add a # constraint to the next block - cur_block.add_cst(offset, AsmConstraint.c_next, - self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(offset) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) break if lines_cpt > 0 and offset in self.split_dis: - cur_block.add_cst(offset, AsmConstraint.c_next, - self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(offset) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) offsets_to_dis.add(offset) break @@ -1512,8 +1635,12 @@ class disasmEngine(object): break if offset in job_done: - cur_block.add_cst(offset, AsmConstraint.c_next, - self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(offset) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) break off_i = offset @@ -1535,12 +1662,16 @@ class disasmEngine(object): if not cur_block.lines: job_done.add(offset) # Block is empty -> bad block - cur_block = AsmBlockBad(label, errno=error) + cur_block = AsmBlockBad(loc_key, errno=error) else: # Block is not empty, stop the desassembly pass and add a # constraint to the next block - cur_block.add_cst(off_i, AsmConstraint.c_next, - self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(off_i) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) break # XXX TODO nul start block option @@ -1548,12 +1679,16 @@ class disasmEngine(object): log_asmblock.warning("reach nul instr at %X", int(off_i)) if not cur_block.lines: # Block is empty -> bad block - cur_block = AsmBlockBad(label, errno=AsmBlockBad.ERROR_NULL_STARTING_BLOCK) + cur_block = AsmBlockBad(loc_key, errno=AsmBlockBad.ERROR_NULL_STARTING_BLOCK) else: # Block is not empty, stop the desassembly pass and add a # constraint to the next block - cur_block.add_cst(off_i, AsmConstraint.c_next, - self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(off_i) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) break # special case: flow graph modificator in delayslot @@ -1579,24 +1714,31 @@ class disasmEngine(object): destinations = instr.getdstflow(self.symbol_pool) known_dsts = [] for dst in destinations: - if not dst.is_label(): + if not dst.is_loc(): continue - label = self.symbol_pool.loc_key_to_label(dst.loc_key) - known_dsts.append(label) - if label.offset in self.dont_dis_retcall_funcs: + loc_key = dst.loc_key + loc_key_offset = self.symbol_pool.loc_key_to_offset(loc_key) + known_dsts.append(loc_key) + if loc_key_offset in self.dont_dis_retcall_funcs: add_next_offset = False if (not instr.is_subcall()) or self.follow_call: - cur_block.bto.update([AsmConstraint(label, AsmConstraint.c_to) for label in known_dsts]) + cur_block.bto.update([AsmConstraint(loc_key, AsmConstraint.c_to) for loc_key in known_dsts]) # get in delayslot mode in_delayslot = True delayslot_count = instr.delayslot for c in cur_block.bto: - offsets_to_dis.add(c.label.offset) + loc_key_offset = self.symbol_pool.loc_key_to_offset(c.loc_key) + offsets_to_dis.add(loc_key_offset) if add_next_offset: - cur_block.add_cst(offset, AsmConstraint.c_next, self.symbol_pool) + loc_key_cst = self.symbol_pool.getby_offset_create(offset) + cur_block.add_cst( + loc_key_cst, + AsmConstraint.c_next, + self.symbol_pool + ) offsets_to_dis.add(offset) # Fix multiple constraints @@ -1652,7 +1794,7 @@ class disasmEngine(object): continue cur_block, nexts = self._dis_block(target_offset, job_done) todo += nexts - blocks.add_node(cur_block) + blocks.add_block(cur_block) blocks.apply_splitting(self.symbol_pool, dis_block_callback=self.dis_block_callback, diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index 8ea96e22..a142ab77 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -1018,11 +1018,11 @@ class instruction(object): args_out = [] for expr in self.args: # try to resolve symbols using symbols (0 for default value) - labels = m2_expr.get_expr_labels(expr) + loc_keys = m2_expr.get_expr_locs(expr) fixed_expr = {} - for exprloc in labels: - label = symbols.loc_key_to_label(exprloc.loc_key) - name = label.name + for exprloc in loc_keys: + loc_key = exprloc.loc_key + name = symbols.loc_key_to_name(loc_key) # special symbols if name == '$': fixed_expr[exprloc] = self.get_asm_offset(exprloc) @@ -1033,16 +1033,18 @@ class instruction(object): if not name in symbols: raise ValueError('Unresolved symbol: %r' % exprloc) - if symbols[name].offset is None: - raise ValueError('The offset of label "%s" cannot be ' - 'determined' % name) + offset = symbols.loc_key_to_offset(loc_key) + if offset is None: + raise ValueError( + 'The offset of loc_key "%s" cannot be determined' % name + ) else: # Fix symbol with its offset size = exprloc.size if size is None: default_size = self.get_symbol_size(exprloc, symbols) size = default_size - value = m2_expr.ExprInt(symbols[name].offset, size) + value = m2_expr.ExprInt(offset, size) fixed_expr[exprloc] = value expr = expr.replace_expr(fixed_expr) diff --git a/miasm2/core/graph.py b/miasm2/core/graph.py index ce17fc75..d88f8721 100644 --- a/miasm2/core/graph.py +++ b/miasm2/core/graph.py @@ -715,11 +715,12 @@ class MatchGraphJoker(object): matched node must be the same than the joker node in the associated MatchGraph @restrict_out: (optional) counterpart of @restrict_in for successors - @filt: (optional) function(node) -> boolean for filtering candidate node + @filt: (optional) function(graph, node) -> boolean for filtering + candidate node @name: (optional) helper for displaying the current joker """ if filt is None: - filt = lambda node: True + filt = lambda graph, node: True self.filt = filt if name is None: name = str(id(self)) @@ -816,7 +817,7 @@ class MatchGraph(DiGraph): return False # Check lambda filtering - if not expected.filt(candidate): + if not expected.filt(graph, candidate): return False # Check arity diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index 07155fd9..86871c37 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -1,7 +1,8 @@ #-*- 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, AstOp @@ -68,21 +69,20 @@ def guess_next_new_label(symbol_pool): name = gen_name % i label = symbol_pool.getby_name(name) if label is None: - return symbol_pool.add_label(name) + return symbol_pool.add_location(name) i += 1 def replace_expr_labels(expr, symbol_pool, replace_id): - """Create AsmLabel of the expression @expr in the @symbol_pool + """Create LocKey of the expression @expr in the @symbol_pool Update @replace_id""" - if not (isinstance(expr, m2_expr.ExprId) and - isinstance(expr.name, asmblock.AsmLabel)): + if not expr.is_loc(): 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) + old_name = symbol_pool.loc_key_to_name(expr.loc_key) + new_lbl = symbol_pool.getby_name_create(old_name) + replace_id[expr] = ExprLoc(new_lbl, expr.size) return replace_id[expr] @@ -103,17 +103,17 @@ STATE_IN_BLOC = 1 def asm_ast_to_expr_with_size(arg, symbol_pool, 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) + 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 + """Parse an assembly listing. Returns a couple (asmcfg, symbol_pool), where + asmcfg is an AsmCfg instance and symbol_pool the associated AsmSymbolPool @mnemo: architecture used @attrib: architecture attribute @@ -224,7 +224,6 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): 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) if instr.dstflow(): @@ -232,12 +231,12 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): 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(symbol_pool) + asmcfg = asmblock.AsmCFG(symbol_pool) block_to_nlink = None delayslot = 0 while i < len(lines): @@ -256,21 +255,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(symbol_pool) + 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 +289,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 @@ -305,7 +308,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None): raise RuntimeError("Cannot have breakflow in delayslot") if line.dstflow(): for dst in line.getdstflow(symbol_pool): - if not isinstance(dst, m2_expr.ExprId): + if not isinstance(dst, ExprId): continue if dst in mnemo.regs.all_regs_ids: continue @@ -319,10 +322,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, symbol_pool diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index 68b4439f..530685db 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -139,22 +139,22 @@ class SemBuilder(object): return self._functions.copy() @staticmethod - def _create_labels(lbl_else=False): + def _create_labels(loc_else=False): """Return the AST standing for label creations - @lbl_else (optional): if set, create a label 'lbl_else'""" - lbl_end = "lbl_end = ir.get_next_label(instr)" - lbl_end_expr = "lbl_end_expr = ExprLoc(lbl_end.loc_key, ir.IRDst.size)" - out = ast.parse(lbl_end).body - out += ast.parse(lbl_end_expr).body - lbl_if = "lbl_if = ir.gen_label()" - lbl_if_expr = "lbl_if_expr = ExprLoc(lbl_if.loc_key, ir.IRDst.size)" - out += ast.parse(lbl_if).body - out += ast.parse(lbl_if_expr).body - if lbl_else: - lbl_else = "lbl_else = ir.gen_label()" - lbl_else_expr = "lbl_else_expr = ExprLoc(lbl_else.loc_key, ir.IRDst.size)" - out += ast.parse(lbl_else).body - out += ast.parse(lbl_else_expr).body + @loc_else (optional): if set, create a label 'loc_else'""" + loc_end = "loc_end = ir.get_next_loc_key(instr)" + loc_end_expr = "loc_end_expr = ExprLoc(loc_end, ir.IRDst.size)" + out = ast.parse(loc_end).body + out += ast.parse(loc_end_expr).body + loc_if = "loc_if = ir.symbol_pool.gen_loc_key()" + loc_if_expr = "loc_if_expr = ExprLoc(loc_if, ir.IRDst.size)" + out += ast.parse(loc_if).body + out += ast.parse(loc_if_expr).body + if loc_else: + loc_else = "loc_else = ir.symbol_pool.gen_loc_key()" + loc_else_expr = "loc_else_expr = ExprLoc(loc_else, ir.IRDst.size)" + out += ast.parse(loc_else).body + out += ast.parse(loc_else_expr).body return out def _parse_body(self, body, argument_names): @@ -203,20 +203,20 @@ class SemBuilder(object): real_body.append(statement) elif isinstance(statement, ast.If): - # Create jumps : ir.IRDst = lbl_if if cond else lbl_end + # Create jumps : ir.IRDst = loc_if if cond else loc_end # if .. else .. are also handled cond = statement.test - real_body += self._create_labels(lbl_else=True) + real_body += self._create_labels(loc_else=True) - lbl_end = ast.Name(id='lbl_end_expr', ctx=ast.Load()) - lbl_if = ast.Name(id='lbl_if_expr', ctx=ast.Load()) - lbl_else = ast.Name(id='lbl_else_expr', ctx=ast.Load()) \ - if statement.orelse else lbl_end + loc_end = ast.Name(id='loc_end_expr', ctx=ast.Load()) + loc_if = ast.Name(id='loc_if_expr', ctx=ast.Load()) + loc_else = ast.Name(id='loc_else_expr', ctx=ast.Load()) \ + if statement.orelse else loc_end dst = ast.Call(func=ast.Name(id='ExprCond', ctx=ast.Load()), args=[cond, - lbl_if, - lbl_else], + loc_if, + loc_else], keywords=[], starargs=None, kwargs=None) @@ -238,10 +238,10 @@ class SemBuilder(object): kwargs=None)) # Create the new blocks - elements = [(statement.body, 'lbl_if')] + elements = [(statement.body, 'loc_if')] if statement.orelse: - elements.append((statement.orelse, 'lbl_else')) - for content, lbl_name in elements: + elements.append((statement.orelse, 'loc_else')) + for content, loc_name in elements: sub_blocks, sub_body = self._parse_body(content, argument_names) if len(sub_blocks) > 1: @@ -250,7 +250,7 @@ class SemBuilder(object): ## Close the last block jmp_end = ast.Call(func=ast.Name(id='ExprAff', ctx=ast.Load()), - args=[IRDst, lbl_end], + args=[IRDst, loc_end], keywords=[], starargs=None, kwargs=None) @@ -269,18 +269,14 @@ class SemBuilder(object): ## Replace the block with a call to 'IRBlock' - lbl_if_name = value= ast.Attribute( - value=ast.Name(id=lbl_name, ctx=ast.Load()), - attr="loc_key", - ctx=ast.Load() - ) + loc_if_name = ast.Name(id=loc_name, ctx=ast.Load()) assignblks = ast.List(elts=[assignblk], ctx=ast.Load()) sub_blocks[-1] = ast.Call(func=ast.Name(id='IRBlock', ctx=ast.Load()), - args=[lbl_if_name, + args=[loc_if_name, assignblks], keywords=[], starargs=None, diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index e0651d7f..5ea596ae 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -118,7 +118,7 @@ class DiGraphExpr(DiGraph): elif isinstance(node, ExprId): return node.name elif isinstance(node, ExprLoc): - return "label_%r" % node.label + return "%s" % node.loc_key elif isinstance(node, ExprMem): return "@%d" % node.size elif isinstance(node, ExprCompose): @@ -168,6 +168,9 @@ class LocKey(object): def __repr__(self): return "<%s %d>" % (self.__class__.__name__, self._key) + def __str__(self): + return "loc_%d" % self.key + # IR definitions class Expr(object): @@ -410,7 +413,7 @@ class Expr(object): def is_id(self, name=None): return False - def is_label(self, label=None): + def is_loc(self, label=None): return False def is_aff(self): @@ -671,7 +674,7 @@ class ExprLoc(Expr): def graph_recursive(self, graph): graph.add_node(self) - def is_label(self, loc_key=None): + def is_loc(self, loc_key=None): if loc_key is not None and self._loc_key != loc_key: return False return True @@ -1483,11 +1486,11 @@ def get_expr_ids_visit(expr, ids): return expr -def get_expr_labels_visit(expr, labels): +def get_expr_locs_visit(expr, locs): """Visitor to retrieve ExprLoc in @expr @expr: Expr""" - if expr.is_label(): - labels.add(expr) + if expr.is_loc(): + locs.add(expr) return expr @@ -1499,12 +1502,12 @@ def get_expr_ids(expr): return ids -def get_expr_labels(expr): +def get_expr_locs(expr): """Retrieve ExprLoc in @expr @expr: Expr""" - ids = set() - expr.visit(lambda x: get_expr_labels_visit(x, ids)) - return ids + locs = set() + expr.visit(lambda x: get_expr_locs_visit(x, locs)) + return locs def test_set(expr, pattern, tks, result): @@ -1546,7 +1549,7 @@ def match_expr(expr, pattern, tks, result=None): elif expr.is_id(): return test_set(expr, pattern, tks, result) - elif expr.is_label(): + elif expr.is_loc(): return test_set(expr, pattern, tks, result) elif expr.is_op(): diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py index 0ea3a836..0a7d1d84 100644 --- a/miasm2/ir/ir.py +++ b/miasm2/ir/ir.py @@ -23,7 +23,7 @@ from itertools import chain import miasm2.expression.expression as m2_expr from miasm2.expression.expression_helper import get_missing_interval -from miasm2.core.asmblock import AsmSymbolPool, AsmLabel, AsmBlock, \ +from miasm2.core.asmblock import AsmSymbolPool, AsmBlock, \ AsmConstraint, AsmBlockBad from miasm2.core.graph import DiGraph @@ -263,17 +263,16 @@ class IRBlock(object): Stand for an intermediate representation basic block. """ - __slots__ = ["label", "_assignblks", "_dst", "_dst_linenb"] + __slots__ = ["_loc_key", "_assignblks", "_dst", "_dst_linenb"] - def __init__(self, label, assignblks): + def __init__(self, loc_key, assignblks): """ - @label: AsmLabel of the IR basic block + @loc_key: LocKey of the IR basic block @assignblks: list of AssignBlock """ - #assert isinstance(label, AsmLabel) - assert isinstance(label, m2_expr.LocKey) - self.label = label + assert isinstance(loc_key, m2_expr.LocKey) + self._loc_key = loc_key for assignblk in assignblks: assert isinstance(assignblk, AssignBlock) self._assignblks = tuple(assignblks) @@ -281,6 +280,13 @@ class IRBlock(object): self._dst_linenb = None + def get_label(self): + warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') + return self.loc_key + + loc_key = property(lambda self:self._loc_key) + label = property(get_label) + @property def assignblks(self): return self._assignblks @@ -340,7 +346,7 @@ class IRBlock(object): else: new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, assignblk.instr)) - return IRBlock(self.label, irs) + return IRBlock(self.loc_key, irs) @property def dst_linenb(self): @@ -351,7 +357,7 @@ class IRBlock(object): def __str__(self): out = [] - out.append('label_%s' % self.label.key) + out.append('loc_key_%s' % self.loc_key.key) for assignblk in self: for dst, src in assignblk.iteritems(): out.append('\t%s = %s' % (dst, src)) @@ -378,7 +384,7 @@ class IRBlock(object): for dst, src in assignblk.iteritems(): new_assignblk[mod_dst(dst)] = mod_src(src) assignblks.append(AssignBlock(new_assignblk, assignblk.instr)) - return IRBlock(self.label, assignblks) + return IRBlock(self.loc_key, assignblks) class irbloc(IRBlock): @@ -387,9 +393,9 @@ class irbloc(IRBlock): Use IRBlock instead of irbloc """ - def __init__(self, label, irs, lines=None): + def __init__(self, loc_key, irs, lines=None): warnings.warn('DEPRECATION WARNING: use "IRBlock" instead of "irblock"') - super(irbloc, self).__init__(label, irs) + super(irbloc, self).__init__(loc_key, irs) class DiGraphIR(DiGraph): @@ -404,20 +410,20 @@ class DiGraphIR(DiGraph): self._blocks = blocks super(DiGraphIR, self).__init__(*args, **kwargs) - def expr_loc_to_symb(self, expr): - if not expr.is_label(): + def _expr_loc_to_symb(self, expr): + if not expr.is_loc(): return expr if self.symbol_pool is None: name = str(expr) else: - name = self.symbol_pool.loc_key_to_label(expr.loc_key).name + name = self.symbol_pool.loc_key_to_name(expr.loc_key) return m2_expr.ExprId(name, expr.size) def node2lines(self, node): if self.symbol_pool is None: node_name = str(node) else: - node_name = self.symbol_pool.loc_key_to_label(node) + node_name = self.symbol_pool.loc_key_to_name(node) yield self.DotCellDescription( text="%s" % node_name, attr={ @@ -431,8 +437,8 @@ class DiGraphIR(DiGraph): raise StopIteration for i, assignblk in enumerate(self._blocks[node]): for dst, src in assignblk.iteritems(): - new_src = src.visit(self.expr_loc_to_symb) - new_dst = dst.visit(self.expr_loc_to_symb) + new_src = src.visit(self._expr_loc_to_symb) + new_dst = dst.visit(self._expr_loc_to_symb) line = "%s = %s" % (new_dst, new_src) if self._dot_offset: yield [self.DotCellDescription(text="%-4d" % i, attr={}), @@ -448,9 +454,9 @@ class DiGraphIR(DiGraph): edge_color = "blue" if isinstance(src_irdst, m2_expr.ExprCond): src1, src2 = src_irdst.src1, src_irdst.src2 - if src1.is_label(dst): + if src1.is_loc(dst): edge_color = "limegreen" - elif src2.is_label(dst): + elif src2.is_loc(dst): edge_color = "red" return {"color": edge_color} @@ -501,24 +507,18 @@ class IntermediateRepresentation(object): irs = [] for assignblk in irb: irs.append(AssignBlock(assignblk, instr)) - extra_irblocks[index] = IRBlock(irb.label, irs) + extra_irblocks[index] = IRBlock(irb.loc_key, irs) assignblk = AssignBlock(ir_bloc_cur, instr) return assignblk, extra_irblocks - def get_label(self, addr): - """Transforms an ExprId/ExprInt/label/int into a label - @addr: an ExprId/ExprInt/label/int""" + def get_loc_key(self, addr): + """Transforms an ExprId/ExprInt/loc_key/int into a loc_key + @addr: an ExprId/ExprInt/loc_key/int""" - if isinstance(addr, AsmLabel): - return addr if isinstance(addr, m2_expr.LocKey): - return self.symbol_pool.loc_key_to_label(addr) + return addr elif isinstance(addr, m2_expr.ExprLoc): - label = self.symbol_pool.loc_key_to_label(addr.loc_key) - if label is None: - return None - else: - return label + return addr.loc_key try: addr = int(addr) @@ -528,13 +528,13 @@ class IntermediateRepresentation(object): return self.symbol_pool.getby_offset_create(addr) def get_block(self, addr): - """Returns the irbloc associated to an ExprId/ExprInt/label/int - @addr: an ExprId/ExprInt/label/int""" + """Returns the irbloc associated to an ExprId/ExprInt/loc_key/int + @addr: an ExprId/ExprInt/loc_key/int""" - label = self.get_label(addr) - if label is None: + loc_key = self.get_loc_key(addr) + if loc_key is None: return None - return self.blocks.get(label.loc_key, None) + return self.blocks.get(loc_key, None) def get_bloc(self, addr): """ @@ -544,18 +544,21 @@ class IntermediateRepresentation(object): warnings.warn('DEPRECATION WARNING: use "get_block" instead of "get_bloc"') return self.get_block(addr) - def add_instr(self, line, addr=0, gen_pc_updt=False): - lbl = self.gen_label() - block = AsmBlock(lbl) + def add_instr(self, line, loc_key=None, gen_pc_updt=False): + if loc_key is None: + loc_key = self.symbol_pool.gen_loc_key() + block = AsmBlock(loc_key) block.lines = [line] self.add_block(block, gen_pc_updt) - return lbl + return loc_key def getby_offset(self, offset): out = set() for irb in self.blocks.values(): for assignblk in irb: instr = assignblk.instr + if instr is None: + continue if instr.offset <= offset < instr.offset + instr.l: out.add(irb) return out @@ -621,28 +624,26 @@ class IntermediateRepresentation(object): @gen_pc_updt: insert PC update effects between instructions """ - label = block.label + loc_key = block.loc_key ir_blocks_all = [] - assert not isinstance(block, AsmBlockBad) - assignments = [] for instr in block.lines: - if label is None: + if loc_key is None: assignments = [] - label = self.get_instr_label(instr) + loc_key = self.get_loc_key_for_instr(instr) split = self.add_instr_to_irblock(block, instr, assignments, ir_blocks_all, gen_pc_updt) if split: - ir_blocks_all.append(IRBlock(label.loc_key, assignments)) - label = None + ir_blocks_all.append(IRBlock(loc_key, assignments)) + loc_key = None assignments = [] - if label is not None: - ir_blocks_all.append(IRBlock(label.loc_key, assignments)) + if loc_key is not None: + ir_blocks_all.append(IRBlock(loc_key, assignments)) new_ir_blocks_all = self.post_add_block(block, ir_blocks_all) for irblock in new_ir_blocks_all: - self.blocks[irblock.label] = irblock + self.blocks[irblock.loc_key] = irblock return new_ir_blocks_all def add_bloc(self, block, gen_pc_updt=False): @@ -675,25 +676,25 @@ class IntermediateRepresentation(object): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue - next_lbl = block.get_next() - if next_lbl is None: - lbl = None + next_loc_key = block.get_next() + if next_loc_key is None: + loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: - lbl = self.symbol_pool.getby_offset_create(line.offset + line.l) - if lbl is None: - lbl = self.symbol_pool.gen_label() - block.add_cst(lbl, AsmConstraint.c_next, self.symbol_pool) + loc_key = self.symbol_pool.getby_offset_create(line.offset + line.l) + if loc_key is None: + loc_key = self.symbol_pool.gen_loc_key() + block.add_cst(loc_key, AsmConstraint.c_next, self.symbol_pool) else: - lbl = next_lbl - dst = m2_expr.ExprLoc(lbl.loc_key, self.pc.size) + loc_key = next_loc_key + dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) - ir_blocks[index] = IRBlock(irblock.label, list(irblock.assignblks) + [assignblk]) + ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk]) def post_add_block(self, block, ir_blocks): self.set_empty_dst_to_next(block, ir_blocks) @@ -701,7 +702,7 @@ class IntermediateRepresentation(object): new_irblocks = [] for irblock in ir_blocks: new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib) - self.blocks[irblock.label] = new_irblock + self.blocks[irblock.loc_key] = new_irblock new_irblocks.append(new_irblock) # Forget graph if any self._graph = None @@ -715,27 +716,22 @@ class IntermediateRepresentation(object): warnings.warn('DEPRECATION WARNING: use "post_add_block" instead of "post_add_bloc"') return self.post_add_block(block, ir_blocks) - def get_instr_label(self, instr): - """Returns the label associated to an instruction + def get_loc_key_for_instr(self, instr): + """Returns the loc_key associated to an instruction @instr: current instruction""" return self.symbol_pool.getby_offset_create(instr.offset) - def gen_label(self): - # TODO: fix hardcoded offset - label = self.symbol_pool.gen_label() - return label - - def gen_label_and_expr(self, size): + def gen_loc_key_and_expr(self, size): """ - Return a label and it's corresponding ExprLoc + Return a loc_key and it's corresponding ExprLoc @size: size of expression """ - label = self.gen_label() - return label, m2_expr.ExprLoc(label.loc_key, size) + loc_key = self.symbol_pool.gen_loc_key() + return loc_key, m2_expr.ExprLoc(loc_key, size) - def get_next_label(self, instr): - label = self.symbol_pool.getby_offset_create(instr.offset + instr.l) - return label + def get_next_loc_key(self, instr): + loc_key = self.symbol_pool.getby_offset_create(instr.offset + instr.l) + return loc_key def simplify(self, simplifier): """ @@ -743,14 +739,14 @@ class IntermediateRepresentation(object): @simplifier: ExpressionSimplifier instance """ modified = False - for label, block in self.blocks.iteritems(): + for loc_key, block in self.blocks.iteritems(): assignblks = [] for assignblk in block: new_assignblk = assignblk.simplify(simplifier) if assignblk != new_assignblk: modified = True assignblks.append(new_assignblk) - self.blocks[label] = IRBlock(label, assignblks) + self.blocks[loc_key] = IRBlock(loc_key, assignblks) return modified def replace_expr_in_ir(self, bloc, rep): @@ -777,7 +773,7 @@ class IntermediateRepresentation(object): out = set() while todo: dst = todo.pop() - if dst.is_label(): + if dst.is_loc(): done.add(dst) elif dst.is_mem() or dst.is_int(): done.add(dst) @@ -826,7 +822,7 @@ class IntermediateRepresentation(object): if dst.is_int(): dst_lbl = self.symbol_pool.getby_offset_create(int(dst)) dst = m2_expr.ExprLoc(dst_lbl.loc_key, self.pc.size) - if dst.is_label(): + if dst.is_loc(): self._graph.add_edge(lbl, dst.loc_key) @property @@ -839,14 +835,14 @@ class IntermediateRepresentation(object): def remove_empty_assignblks(self): modified = False - for label, block in self.blocks.iteritems(): + for loc_key, block in self.blocks.iteritems(): irs = [] for assignblk in block: if len(assignblk): irs.append(assignblk) else: modified = True - self.blocks[label] = IRBlock(label, irs) + self.blocks[loc_key] = IRBlock(loc_key, irs) return modified def remove_jmp_blocks(self): @@ -864,62 +860,62 @@ class IntermediateRepresentation(object): if len(assignblk) > 1: continue assert set(assignblk.keys()) == set([self.IRDst]) - if len(self.graph.successors(block.label)) != 1: + if len(self.graph.successors(block.loc_key)) != 1: continue - if not assignblk[self.IRDst].is_label(): + if not assignblk[self.IRDst].is_loc(): continue dst = assignblk[self.IRDst].loc_key - if dst == block.label: + if dst == block.loc_key: # Infinite loop block continue - jmp_blocks.add(block.label) + jmp_blocks.add(block.loc_key) # Remove them, relink graph modified = False - for label in jmp_blocks: - block = self.blocks[label] + for loc_key in jmp_blocks: + block = self.blocks[loc_key] dst_loc_key = block.dst - parents = self.graph.predecessors(block.label) + parents = self.graph.predecessors(block.loc_key) for lbl in parents: parent = self.blocks.get(lbl, None) if parent is None: continue dst = parent.dst - if dst.is_id(block.label): + if dst.is_id(block.loc_key): dst = m2_expr.ExprLoc(dst_loc_key, dst.size) - self.graph.discard_edge(lbl, block.label) - self.graph.discard_edge(block.label, dst_label) + self.graph.discard_edge(lbl, block.loc_key) + self.graph.discard_edge(block.loc_key, dst_loc_key) - self.graph.add_uniq_edge(lbl, dst_label) + self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True elif dst.is_cond(): src1, src2 = dst.src1, dst.src2 - if src1.is_id(block.label): - dst = m2_expr.ExprCond(dst.cond, m2_expr.ExprLoc(dst_label, dst.size), dst.src2) - self.graph.discard_edge(lbl, block.label) - self.graph.discard_edge(block.label, dst_label) - self.graph.add_uniq_edge(lbl, dst_label) + if src1.is_id(block.loc_key): + dst = m2_expr.ExprCond(dst.cond, m2_expr.ExprLoc(dst_loc_key, dst.size), dst.src2) + self.graph.discard_edge(lbl, block.loc_key) + self.graph.discard_edge(block.loc_key, dst_loc_key) + self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True - if src2.is_id(block.label): - dst = m2_expr.ExprCond(dst.cond, dst.src1, m2_expr.ExprLoc(dst_label, dst.size)) - self.graph.discard_edge(lbl, block.label) - self.graph.discard_edge(block.label, dst_label) - self.graph.add_uniq_edge(lbl, dst_label) + if src2.is_id(block.loc_key): + dst = m2_expr.ExprCond(dst.cond, dst.src1, m2_expr.ExprLoc(dst_loc_key, dst.size)) + self.graph.discard_edge(lbl, block.loc_key) + self.graph.discard_edge(block.loc_key, dst_loc_key) + self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True if dst.src1 == dst.src2: dst = dst.src1 else: continue new_parent = parent.set_dst(dst) - self.blocks[parent.label] = new_parent + self.blocks[parent.loc_key] = new_parent # Remove unlinked useless nodes - for label in jmp_blocks: - if (len(self.graph.predecessors(label)) == 0 and - len(self.graph.successors(label)) == 0): - self.graph.del_node(label) - del self.blocks[label] + for loc_key in jmp_blocks: + if (len(self.graph.predecessors(loc_key)) == 0 and + len(self.graph.successors(loc_key)) == 0): + self.graph.del_node(loc_key) + del self.blocks[loc_key] return modified def merge_blocks(self): @@ -976,6 +972,6 @@ class ir(IntermediateRepresentation): Use IntermediateRepresentation instead of ir """ - def __init__(self, label, irs, lines=None): + def __init__(self, loc_key, irs, lines=None): warnings.warn('DEPRECATION WARNING: use "IntermediateRepresentation" instead of "ir"') - super(ir, self).__init__(label, irs, lines) + super(ir, self).__init__(loc_key, irs, lines) diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index d78298a3..7ee55f97 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -17,9 +17,10 @@ log.setLevel(logging.INFO) def get_block(ir_arch, mdis, addr): """Get IRBlock at address @addr""" - lbl = ir_arch.get_label(addr) + lbl = ir_arch.get_loc_key(addr) if not lbl in ir_arch.blocks: - block = mdis.dis_block(lbl.offset) + offset = mdis.symbol_pool.loc_key_to_offset(lbl) + block = mdis.dis_block(offset) ir_arch.add_block(block) irblock = ir_arch.get_block(lbl) if irblock is None: @@ -891,9 +892,9 @@ class SymbolicExecutionEngine(object): def eval_exprloc(self, expr, **kwargs): """[DEV]: Evaluate an ExprLoc using the current state""" - label = self.ir_arch.symbol_pool.loc_key_to_label(expr.loc_key) - if label.offset is not None: - ret = ExprInt(label.offset, expr.size) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key) + if offset is not None: + ret = ExprInt(offset, expr.size) else: ret = expr return ret @@ -1050,11 +1051,11 @@ class SymbolicExecutionEngine(object): dst = self.eval_expr(self.ir_arch.IRDst) # Best effort to resolve destination as ExprLoc - if dst.is_label(): + if dst.is_loc(): ret = dst elif dst.is_int(): label = self.ir_arch.symbol_pool.getby_offset_create(int(dst)) - ret = ExprLoc(label.loc_key, dst.size) + ret = ExprLoc(label, dst.size) else: ret = dst return ret @@ -1074,14 +1075,14 @@ class SymbolicExecutionEngine(object): """ Symbolic execution starting at @addr @addr: address to execute (int or ExprInt or label) - @lbl_stop: AsmLabel to stop execution on + @lbl_stop: LocKey to stop execution on @step: display intermediate steps """ while True: irblock = self.ir_arch.get_block(addr) if irblock is None: break - if irblock.label == lbl_stop: + if irblock.loc_key == lbl_stop: break addr = self.eval_updt_irblock(irblock, step=step) return addr diff --git a/miasm2/ir/symbexec_top.py b/miasm2/ir/symbexec_top.py index 1e1e76e9..64d428b4 100644 --- a/miasm2/ir/symbexec_top.py +++ b/miasm2/ir/symbexec_top.py @@ -121,14 +121,20 @@ class SymbExecTopNoMem(SymbolicExecutionEngine): def eval_exprid(self, expr, **kwargs): """[DEV]: Evaluate an ExprId using the current state""" - if isinstance(expr.name, asmblock.AsmLabel) and expr.name.offset is not None: - ret = ExprInt(expr.name.offset, expr.size) - elif expr in self.regstop: + if expr in self.regstop: ret = exprid_top(expr) else: ret = self.symbols.read(expr) return ret + def eval_exprloc(self, expr, **kwargs): + offset = self.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key) + if offset is not None: + ret = ExprInt(offset, expr.size) + else: + ret = expr + return ret + def eval_exprcond(self, expr, **kwargs): """[DEV]: Evaluate an ExprCond using the current state""" cond = self.eval_expr_visitor(expr.cond, **kwargs) diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index a8e3a254..2f354d47 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -39,8 +39,6 @@ class TranslatorC(Translator): return "0x%x" % mask def from_ExprId(self, expr): - if isinstance(expr.name, asmblock.AsmLabel): - return "0x%x" % expr.name.offset return str(expr) def from_ExprInt(self, expr): @@ -56,6 +54,7 @@ class TranslatorC(Translator): loc_key = expr.loc_key if self.symbol_pool is None: return str(loc_key) + offset = self.symbol_pool.loc_key_to_offset(loc_key) name = self.symbol_pool.loc_key_to_name(loc_key) diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py index 6a6fec16..f5d633e0 100644 --- a/miasm2/ir/translators/smt2.py +++ b/miasm2/ir/translators/smt2.py @@ -1,7 +1,6 @@ import logging import operator -from miasm2.core.asmblock import AsmLabel from miasm2.ir.translators.translator import Translator from miasm2.expression.smt2_helper import * @@ -136,19 +135,9 @@ class TranslatorSMT2(Translator): return bit_vec_val(expr.arg.arg, expr.size) def from_ExprId(self, expr): - if isinstance(expr.name, AsmLabel): - if expr.name.offset is not None: - return bit_vec_val(str(expr.name.offset), expr.size) - else: - # SMT2-escape expression name - name = "|{}|".format(str(expr.name)) - if name not in self._bitvectors: - self._bitvectors[name] = expr.size - return name - else: - if str(expr) not in self._bitvectors: - self._bitvectors[str(expr)] = expr.size - return str(expr) + if str(expr) not in self._bitvectors: + self._bitvectors[str(expr)] = expr.size + return str(expr) def from_ExprLoc(self, expr): loc_key = expr.loc_key diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py index 544dd26f..d01b73fa 100644 --- a/miasm2/ir/translators/z3_ir.py +++ b/miasm2/ir/translators/z3_ir.py @@ -5,7 +5,6 @@ import operator # Raise an ImportError if z3 is not available WITHOUT actually importing it imp.find_module("z3") -from miasm2.core.asmblock import AsmLabel from miasm2.ir.translators.translator import Translator log = logging.getLogger("translator_z3") @@ -133,22 +132,21 @@ class TranslatorZ3(Translator): return z3.BitVecVal(expr.arg.arg, expr.size) def from_ExprId(self, expr): - if isinstance(expr.name, AsmLabel) and expr.name.offset is not None: - return z3.BitVecVal(expr.name.offset, expr.size) - else: - return z3.BitVec(str(expr), expr.size) + return z3.BitVec(str(expr), expr.size) def from_ExprLoc(self, expr): if self.symbol_pool is None: # No symbol_pool, fallback to default name return z3.BitVec(str(expr), expr.size) - label = self.symbol_pool.loc_key_to_label(expr.loc_key) - if label is None: - # No symbol_pool, fallback to default name - return z3.BitVec(str(expr), expr.size) - elif label.offset is None: - return z3.BitVec(label.name, expr.size) - return z3.BitVecVal(label.offset, expr.size) + loc_key = expr.loc_key + offset = self.symbol_pool.loc_key_to_offset(loc_key) + name = self.symbol_pool.loc_key_to_name(loc_key) + if offset is not None: + return z3.BitVecVal(offset, expr.size) + if name is not None: + return z3.BitVec(name, expr.size) + # fallback to default name + return z3.BitVec(str(loc_key), expr.size) def from_ExprMem(self, expr): addr = self.from_expr(expr.arg) diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py index 519664e3..c6232642 100644 --- a/miasm2/jitter/codegen.py +++ b/miasm2/jitter/codegen.py @@ -2,7 +2,8 @@ Module to generate C code for a given native @block """ -import miasm2.expression.expression as m2_expr +from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \ + ExprMem, ExprCond, LocKey from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.ir.translators.C import TranslatorC @@ -108,20 +109,20 @@ class CGen(object): """Iinitialize jitter internals""" self.id_to_c_id = {} for reg in self.ir_arch.arch.regs.all_regs_ids: - self.id_to_c_id[reg] = m2_expr.ExprId('mycpu->%s' % reg, reg.size) + self.id_to_c_id[reg] = ExprId('mycpu->%s' % reg, reg.size) self.C_PC = self.id_to_c(self.PC) - @staticmethod - def label_to_jitlabel(lbl): - """Convert AsmLabel to a jitter label name""" - assert lbl.offset is not None - return "jitblock_%X" % lbl.offset + def loc_key_to_jitlabel(self, lbl): + """Convert LocKey to a jitter label name""" + offset = self.ir_arch.symbol_pool.loc_key_to_offset(lbl) + assert offset is not None + return "jitblock_%X" % offset def dst_to_c(self, src): """Translate Expr @src into C code""" - if not isinstance(src, m2_expr.Expr): - src = m2_expr.ExprInt(src, self.PC.size) + if not isinstance(src, Expr): + src = ExprInt(src, self.PC.size) return self.id_to_c(src) def patch_c_id(self, expr): @@ -132,12 +133,12 @@ class CGen(object): """Translate Expr @expr into corresponding C code""" return self.translator.from_expr(self.patch_c_id(expr)) - def add_label_index(self, dst2index, lbl): + def add_label_index(self, dst2index, loc_key): """Insert @lbl to the dictionnary @dst2index with a uniq value - @dst2index: AsmLabel -> uniq value - @lbl: AsmLabel istance""" + @dst2index: LocKey -> uniq value + @loc_key: LocKey istance""" - dst2index[lbl] = len(dst2index) + dst2index[loc_key] = len(dst2index) def assignblk_to_irbloc(self, instr, assignblk): """ @@ -148,10 +149,11 @@ class CGen(object): new_assignblk = dict(assignblk) if self.ir_arch.IRDst not in assignblk: offset = instr.offset + instr.l - dst = m2_expr.ExprInt(offset, self.ir_arch.IRDst.size) + loc_key = self.ir_arch.symbol_pool.getby_offset_create(offset) + dst = ExprLoc(loc_key, self.ir_arch.IRDst.size) new_assignblk[self.ir_arch.IRDst] = dst irs = [AssignBlock(new_assignblk, instr)] - return IRBlock(self.ir_arch.get_instr_label(instr).loc_key, irs) + return IRBlock(self.ir_arch.get_loc_key_for_instr(instr), irs) def block2assignblks(self, block): """ @@ -169,6 +171,7 @@ class CGen(object): for irblock in irblocks: assert irblock.dst is not None irblocks_list.append(irblocks) + return irblocks_list def add_local_var(self, dst_var, dst_index, expr): @@ -184,7 +187,7 @@ class CGen(object): if size not in dst_index: raise RuntimeError("Unsupported operand size %s", size) var_num = dst_index[size] - dst = m2_expr.ExprId("var_%.2d_%.2d" % (size, var_num), size) + dst = ExprId("var_%.2d_%.2d" % (size, var_num), size) dst_index[size] += 1 dst_var[expr] = dst return dst @@ -200,12 +203,13 @@ class CGen(object): # Prefetch memory read for expr in assignblk.get_r(mem_read=True): - if not isinstance(expr, m2_expr.ExprMem): + if not isinstance(expr, ExprMem): continue var_num = mem_index[expr.size] mem_index[expr.size] += 1 - var = m2_expr.ExprId( - "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size) + var = ExprId( + "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size + ) mem_var[expr] = var # Generate memory prefetch @@ -239,7 +243,7 @@ class CGen(object): src = src.replace_expr(prefetchers) if dst is self.ir_arch.IRDst: pass - elif isinstance(dst, m2_expr.ExprId): + elif isinstance(dst, ExprId): new_dst = self.add_local_var(dst_var, dst_index, dst) if dst in self.ir_arch.arch.regs.regs_flt_expr: # Dont mask float affectation @@ -250,9 +254,9 @@ class CGen(object): '%s = (%s)&%s;' % (self.id_to_c(new_dst), self.id_to_c(src), SIZE_TO_MASK[src.size])) - elif isinstance(dst, m2_expr.ExprMem): + elif isinstance(dst, ExprMem): ptr = dst.arg.replace_expr(prefetchers) - new_dst = m2_expr.ExprMem(ptr, dst.size) + new_dst = ExprMem(ptr, dst.size) str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE') c_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src))) else: @@ -284,25 +288,25 @@ class CGen(object): @dst2index: dictionnary to link label to its index """ - if isinstance(expr, m2_expr.ExprCond): + if isinstance(expr, ExprCond): cond = self.id_to_c(expr.cond) src1, src1b = self.traverse_expr_dst(expr.src1, dst2index) src2, src2b = self.traverse_expr_dst(expr.src2, dst2index) return ("((%s)?(%s):(%s))" % (cond, src1, src2), "((%s)?(%s):(%s))" % (cond, src1b, src2b)) - if isinstance(expr, m2_expr.ExprInt): + if isinstance(expr, ExprInt): offset = int(expr) - self.add_label_index(dst2index, offset) - return ("%s" % dst2index[offset], hex(offset)) - if expr.is_label(): - label = self.ir_arch.symbol_pool.loc_key_to_label(expr.loc_key) - if label.offset != None: - offset = label.offset - self.add_label_index(dst2index, offset) - return ("%s" % dst2index[offset], hex(offset)) - self.add_label_index(dst2index, label) - return ("%s" % dst2index[label], "0") - + loc_key = self.ir_arch.symbol_pool.getby_offset_create(offset) + self.add_label_index(dst2index, loc_key) + return ("%s" % dst2index[loc_key], hex(offset)) + if expr.is_loc(): + loc_key = expr.loc_key + offset = self.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key) + if offset is not None: + self.add_label_index(dst2index, loc_key) + return ("%s" % dst2index[loc_key], hex(offset)) + self.add_label_index(dst2index, loc_key) + return ("%s" % dst2index[loc_key], "0") dst2index[expr] = -1 return ("-1", self.id_to_c(expr)) @@ -355,24 +359,28 @@ class CGen(object): @attrib: instruction Attributes @instr_offsets: instructions offsets list @dst: potential instruction destination""" - if isinstance(dst, AsmLabel) and dst.offset is None: - # Generate goto for local labels - return ['goto %s;' % dst.name] - offset = None - if isinstance(dst, AsmLabel) and dst.offset is not None: - offset = dst.offset - elif isinstance(dst, (int, long)): - offset = dst + out = [] - if (offset is not None and - offset > attrib.instr.offset and + if isinstance(dst, Expr): + out += self.gen_post_code(attrib) + out.append('BlockDst->address = DST_value;') + out += self.gen_post_instr_checks(attrib) + out.append('\t\treturn JIT_RET_NO_EXCEPTION;') + return out + + assert isinstance(dst, LocKey) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(dst) + if offset is None: + # Generate goto for local labels + name = self.ir_arch.symbol_pool.loc_key_to_name(dst) + return ['goto %s;' % name] + if (offset > attrib.instr.offset and offset in instr_offsets): # Only generate goto for next instructions. # (consecutive instructions) - lbl = self.ir_arch.symbol_pool.getby_offset_create(dst) out += self.gen_post_code(attrib) out += self.gen_post_instr_checks(attrib) - out.append('goto %s;' % self.label_to_jitlabel(lbl)) + out.append('goto %s;' % self.loc_key_to_jitlabel(dst)) else: out += self.gen_post_code(attrib) out.append('BlockDst->address = DST_value;') @@ -468,10 +476,10 @@ class CGen(object): element_read = assignblk.get_r(mem_read=True) # Check mem read - attrib.mem_read = any(isinstance(expr, m2_expr.ExprMem) + attrib.mem_read = any(isinstance(expr, ExprMem) for expr in element_read) # Check mem write - attrib.mem_write = any(isinstance(dst, m2_expr.ExprMem) + attrib.mem_write = any(isinstance(dst, ExprMem) for dst in assignblk) def get_attributes(self, instr, irblocks, log_mn=False, log_regs=False): @@ -522,9 +530,11 @@ class CGen(object): """ instr_offsets = [line.offset for line in block.lines] - instr_offsets.append(self.get_block_post_label(block).offset) + post_label = self.get_block_post_label(block) + post_offset = self.ir_arch.symbol_pool.loc_key_to_offset(post_label) + instr_offsets.append(post_offset) lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0]) - return (self.CODE_INIT % self.label_to_jitlabel(lbl_start)).split("\n"), instr_offsets + return (self.CODE_INIT % self.loc_key_to_jitlabel(lbl_start)).split("\n"), instr_offsets def gen_irblock(self, instr_attrib, attributes, instr_offsets, irblock): """ @@ -557,8 +567,9 @@ class CGen(object): """ lbl = self.get_block_post_label(block) - dst = self.dst_to_c(lbl.offset) - code = self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), self.C_PC, dst, dst) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(lbl) + dst = self.dst_to_c(offset) + code = self.CODE_RETURN_NO_EXCEPTION % (self.loc_key_to_jitlabel(lbl), self.C_PC, dst, dst) return code.split('\n') def gen_c(self, block, log_mn=False, log_regs=False): @@ -571,24 +582,25 @@ class CGen(object): if isinstance(block, AsmBlockBad): return self.gen_bad_block() irblocks_list = self.block2assignblks(block) - out, instr_offsets = self.gen_init(block) assert len(block.lines) == len(irblocks_list) for instr, irblocks in zip(block.lines, irblocks_list): instr_attrib, irblocks_attributes = self.get_attributes(instr, irblocks, log_mn, log_regs) - for index, irblock in enumerate(irblocks): new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(irblock, self.ir_arch.attrib) - label = self.ir_arch.symbol_pool.loc_key_to_label(new_irblock.label) - if label.offset is None: + label = new_irblock.loc_key + offset = self.ir_arch.symbol_pool.loc_key_to_offset(label) + if offset is None: + name = self.ir_arch.symbol_pool.loc_key_to_name(label) out.append("%-40s // %.16X %s" % - (str(label.name) + ":", instr.offset, instr)) + (str(name) + ":", instr.offset, instr)) else: out.append("%-40s // %.16X %s" % - (self.label_to_jitlabel(label) + ":", instr.offset, instr)) + (self.loc_key_to_jitlabel(label) + ":", instr.offset, instr)) if index == 0: out += self.gen_pre_code(instr_attrib) out += self.gen_irblock(instr_attrib, irblocks_attributes[index], instr_offsets, new_irblock) out += self.gen_finalize(block) + return ['\t' + line for line in out] diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py index 4402ef49..8fd3453e 100644 --- a/miasm2/jitter/jitcore.py +++ b/miasm2/jitter/jitcore.py @@ -17,9 +17,10 @@ # from hashlib import md5 -from miasm2.core.asmblock import disasmEngine, AsmLabel, AsmBlockBad +from miasm2.core.asmblock import disasmEngine, AsmBlockBad from miasm2.core.interval import interval from miasm2.core.utils import BoundedDict +from miasm2.expression.expression import LocKey from miasm2.jitter.csts import * @@ -40,7 +41,7 @@ class JitCore(object): self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib) self.bs = bs self.known_blocs = {} - self.lbl2jitbloc = BoundedDict(self.jitted_block_max_size, + self.loc_key_to_jit_block = BoundedDict(self.jitted_block_max_size, delete_cb=self.jitted_block_delete_cb) self.lbl2bloc = {} self.log_mn = False @@ -75,7 +76,7 @@ class JitCore(object): def clear_jitted_blocks(self): "Reset all jitted blocks" - self.lbl2jitbloc.clear() + self.loc_key_to_jit_block.clear() self.lbl2bloc.clear() self.blocs_mem_interval = interval() @@ -100,8 +101,9 @@ class JitCore(object): cur_block.ad_max = cur_block.lines[-1].offset + cur_block.lines[-1].l else: # 1 byte block for unknown mnemonic - cur_block.ad_min = cur_block.label.offset - cur_block.ad_max = cur_block.label.offset+1 + offset = ir_arch.symbol_pool.loc_key_to_offset(cur_block.loc_key) + cur_block.ad_min = offset + cur_block.ad_max = offset+1 def add_bloc_to_mem_interval(self, vm, block): @@ -125,20 +127,21 @@ class JitCore(object): """Add a block to JiT and JiT it. @block: asm_bloc to add """ - irblocks = self.ir_arch.add_block(block, gen_pc_updt = True) block.blocks = irblocks - self.jitirblocs(block.label, irblocks) + self.jitirblocs(block.loc_key, irblocks) def disbloc(self, addr, vm): """Disassemble a new block and JiT it - @addr: address of the block to disassemble (AsmLabel or int) + @addr: address of the block to disassemble (LocKey or int) @vm: VmMngr instance """ # Get the block - if isinstance(addr, AsmLabel): - addr = addr.offset + if isinstance(addr, LocKey): + addr = self.ir_arch.symbol_pool.loc_key_to_offset(addr) + if addr is None: + raise RuntimeError("Unknown offset for LocKey") # Prepare disassembler self.mdis.lines_wd = self.options["jit_maxline"] @@ -153,7 +156,7 @@ class JitCore(object): print cur_block # Update label -> block - self.lbl2bloc[cur_block.label] = cur_block + self.lbl2bloc[cur_block.loc_key] = cur_block # Store min/max block address needed in jit automod code self.get_bloc_min_max(cur_block) @@ -174,7 +177,7 @@ class JitCore(object): if lbl is None: lbl = getattr(cpu, self.ir_arch.pc.name) - if not lbl in self.lbl2jitbloc: + if not lbl in self.loc_key_to_jit_block: # Need to JiT the block cur_block = self.disbloc(lbl, cpu.vmmngr) if isinstance(cur_block, AsmBlockBad): @@ -188,7 +191,7 @@ class JitCore(object): return lbl # Run the block and update cpu/vmmngr state - return self.exec_wrapper(lbl, cpu, self.lbl2jitbloc.data, breakpoints, + return self.exec_wrapper(lbl, cpu, self.loc_key_to_jit_block.data, breakpoints, self.options["max_exec_per_call"]) def blocs2memrange(self, blocks): @@ -245,16 +248,18 @@ class JitCore(object): try: for irblock in block.blocks: # Remove offset -> jitted block link - if irblock.label.offset in self.lbl2jitbloc: - del(self.lbl2jitbloc[irblock.label.offset]) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(irblock.loc_key) + if offset in self.loc_key_to_jit_block: + del(self.loc_key_to_jit_block[offset]) except AttributeError: # The block has never been translated in IR - if block.label.offset in self.lbl2jitbloc: - del(self.lbl2jitbloc[block.label.offset]) + offset = self.ir_arch.symbol_pool.loc_key_to_offset(block.loc_key) + if offset in self.loc_key_to_jit_block: + del(self.loc_key_to_jit_block[offset]) # Remove label -> block link - del(self.lbl2bloc[block.label]) + del(self.lbl2bloc[block.loc_key]) return modified_blocks @@ -283,7 +288,8 @@ class JitCore(object): @block: asmblock """ block_raw = "".join(line.b for line in block.lines) - block_hash = md5("%X_%s_%s_%s_%s" % (block.label.offset, + offset = self.ir_arch.symbol_pool.loc_key_to_offset(block.loc_key) + block_hash = md5("%X_%s_%s_%s_%s" % (offset, self.arch_name, self.log_mn, self.log_regs, diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py index 4dd8825a..f0a75cf4 100644 --- a/miasm2/jitter/jitcore_cc_base.py +++ b/miasm2/jitter/jitcore_cc_base.py @@ -85,20 +85,20 @@ class JitCore_Cc_Base(JitCore): """ self.codegen = codegen - def label2fname(self, label): + def loc_key_to_filename(self, loc_key): """ - Generate function name from @label - @label: AsmLabel instance + Generate function name from @loc_key + @loc_key: LocKey instance """ - return "block_%s" % self.codegen.label_to_jitlabel(label) + return "block_%s" % self.codegen.loc_key_to_jitlabel(loc_key) - def gen_c_code(self, label, block): + def gen_c_code(self, loc_key, block): """ Return the C code corresponding to the @irblocks - @label: AsmLabel of the block to jit + @loc_key: LocKey of the block to jit @irblocks: list of irblocks """ - f_name = self.label2fname(label) + f_name = self.loc_key_to_filename(loc_key) f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs) out = [f_declaration + '{'] + out + ['}\n'] diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py index ccccc37a..d9da3160 100644 --- a/miasm2/jitter/jitcore_gcc.py +++ b/miasm2/jitter/jitcore_gcc.py @@ -25,12 +25,13 @@ class JitCore_Gcc(JitCore_Cc_Base): del self.states[offset] def load_code(self, label, fname_so): - f_name = self.label2fname(label) + f_name = self.loc_key_to_filename(label) lib = ctypes.cdll.LoadLibrary(fname_so) func = getattr(lib, f_name) addr = ctypes.cast(func, ctypes.c_void_p).value - self.lbl2jitbloc[label.offset] = addr - self.states[label.offset] = lib + offset = self.ir_arch.symbol_pool.loc_key_to_offset(label) + self.loc_key_to_jit_block[offset] = addr + self.states[offset] = lib def add_bloc(self, block): """Add a bloc to JiT and JiT it. @@ -40,7 +41,7 @@ class JitCore_Gcc(JitCore_Cc_Base): fname_out = os.path.join(self.tempdir, "%s.so" % block_hash) if not os.access(fname_out, os.R_OK | os.X_OK): - func_code = self.gen_c_code(block.label, block) + func_code = self.gen_c_code(block.loc_key, block) # Create unique C file fdesc, fname_in = tempfile.mkstemp(suffix=".c") @@ -60,7 +61,7 @@ class JitCore_Gcc(JitCore_Cc_Base): os.rename(fname_tmp, fname_out) os.remove(fname_in) - self.load_code(block.label, fname_out) + self.load_code(block.loc_key, fname_out) @staticmethod def gen_C_source(ir_arch, func_code): diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py index a8d30f46..5152cf9e 100644 --- a/miasm2/jitter/jitcore_llvm.py +++ b/miasm2/jitter/jitcore_llvm.py @@ -84,7 +84,7 @@ class JitCore_LLVM(jitcore.JitCore): if not os.access(fname_out, os.R_OK): # Build a function in the context - func = LLVMFunction(self.context, block.label) + func = LLVMFunction(self.context, block.loc_key) # Set log level func.log_regs = self.log_regs @@ -115,7 +115,9 @@ class JitCore_LLVM(jitcore.JitCore): else: # The cache file exists: function can be loaded from cache - ptr = self.context.get_ptr_from_cache(fname_out, block.label) + ptr = self.context.get_ptr_from_cache(fname_out, block.loc_key) # Store a pointer on the function jitted code - self.lbl2jitbloc[block.label.offset] = ptr + loc_key = block.loc_key + offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key) + self.loc_key_to_jit_block[offset] = ptr diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index af9f09e6..785e3fa1 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -34,9 +34,9 @@ class JitCore_Python(jitcore.JitCore): "Preload symbols according to current architecture" self.symbexec.reset_regs() - def jitirblocs(self, label, irblocks): + def jitirblocs(self, loc_key, irblocks): """Create a python function corresponding to an irblocks' group. - @label: the label of the irblocks + @loc_key: the loc_key of the irblocks @irblocks: a gorup of irblocks """ @@ -48,7 +48,7 @@ class JitCore_Python(jitcore.JitCore): vmmngr = cpu.vmmngr # Keep current location in irblocks - cur_label = label.loc_key + cur_loc_key = loc_key # Required to detect new instructions offsets_jitted = set() @@ -57,13 +57,12 @@ class JitCore_Python(jitcore.JitCore): exec_engine = self.symbexec expr_simp = exec_engine.expr_simp - known_loc_keys = set(irb.label for irb in irblocks) + known_loc_keys = set(irb.loc_key for irb in irblocks) # For each irbloc inside irblocks while True: - # Get the current bloc for irb in irblocks: - if irb.label == cur_label: + if irb.loc_key == cur_loc_key: break else: @@ -123,24 +122,24 @@ class JitCore_Python(jitcore.JitCore): if isinstance(ad, m2_expr.ExprInt): return ad.arg.arg elif isinstance(ad, m2_expr.ExprLoc): - cur_label = ad.loc_key - if cur_label not in known_loc_keys: - return cur_label + cur_loc_key = ad.loc_key else: raise NotImplementedError("Type not handled: %s" % ad) - # Associate myfunc with current label - self.lbl2jitbloc[label.offset] = myfunc + # Associate myfunc with current loc_key + offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key) + assert offset is not None + self.loc_key_to_jit_block[offset] = myfunc - def exec_wrapper(self, label, cpu, _lbl2jitbloc, _breakpoints, + def exec_wrapper(self, loc_key, cpu, _loc_key_to_jit_block, _breakpoints, _max_exec_per_call): - """Call the function @label with @cpu - @label: function's label + """Call the function @loc_key with @cpu + @loc_key: function's loc_key @cpu: JitCpu instance """ - # Get Python function corresponding to @label - fc_ptr = self.lbl2jitbloc[label] + # Get Python function corresponding to @loc_key + fc_ptr = self.loc_key_to_jit_block[loc_key] # Execute the function return fc_ptr(cpu) diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py index 3f7d0c6d..2045f083 100644 --- a/miasm2/jitter/llvmconvert.py +++ b/miasm2/jitter/llvmconvert.py @@ -14,7 +14,8 @@ import os from llvmlite import binding as llvm from llvmlite import ir as llvm_ir -import miasm2.expression.expression as m2_expr +from miasm2.expression.expression import ExprId, ExprInt, ExprMem, ExprSlice, \ + ExprCond, ExprLoc, ExprOp, ExprCompose, LocKey import miasm2.jitter.csts as m2_csts import miasm2.core.asmblock as m2_asmblock from miasm2.jitter.codegen import CGen @@ -43,7 +44,7 @@ class LLVMType(llvm_ir.Type): @classmethod def generic(cls, e): "Generic value for execution" - if isinstance(e, m2_expr.ExprInt): + if isinstance(e, ExprInt): return llvm_e.GenericValue.int(LLVMType.IntType(e.size), int(e.arg)) elif isinstance(e, llvm_e.GenericValue): return e @@ -69,25 +70,21 @@ class LLVMContext(): self.target_machine = target.create_target_machine() self.init_exec_engine() - def canonize_label_name(self, label): """Canonize @label names to a common form. @label: str or asmlabel instance""" if isinstance(label, str): return label - if isinstance(label, m2_expr.Expr) and expr.is_label(): - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label.index) - if isinstance(label, (int, long)): - fds - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label) - - if isinstance(label, m2_asmblock.AsmLabel): - if label.offset is None: - return "label_%s" % label.name - else: - return "label_%X" % label.offset + if not isinstance(label, LocKey): + raise ValueError("label must either be str or LocKey") + + offset = self.ir_arch.symbol_pool.loc_key_to_offset(label) + + if offset is None: + name = self.ir_arch.symbol_pool.loc_key_to_name(label) + return "%s" % name else: - raise ValueError("label must either be str or asmlabel") + return "label_off_%X" % offset def optimise_level(self, level=2): """Set the optimisation level to @level from 0 to 2 @@ -400,8 +397,8 @@ class LLVMFunction(): def __init__(self, llvm_context, name="fc", new_module=True): "Create a new function with name @name" - name = self.canonize_label_name(name) self.llvm_context = llvm_context + name = self.llvm_context.canonize_label_name(name) if new_module: self.llvm_context.new_module() self.mod = self.llvm_context.get_module() @@ -427,7 +424,7 @@ class LLVMFunction(): @label: str or asmlabel @overwrite: if False, do nothing if a bbl with the same name already exists Return the corresponding LLVM Basic Block""" - name = self.canonize_label_name(label) + name = self.llvm_context.canonize_label_name(label) bbl = self.name2bbl.get(name, None) if not overwrite and bbl is not None: return bbl @@ -505,27 +502,9 @@ class LLVMFunction(): var_casted = var self.builder.ret(var_casted) - def canonize_label_name(self, label): - """Canonize @label names to a common form. - @label: str or asmlabel instance""" - if isinstance(label, str): - return label - if isinstance(label, m2_expr.Expr) and expr.is_label(): - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label.index) - if isinstance(label, m2_expr.LocKey): - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label) - - if isinstance(label, m2_asmblock.AsmLabel): - if label.offset is None: - return "label_%s" % label.name - else: - return "label_%X" % label.offset - else: - raise ValueError("label must either be str or asmlabel") - - def get_basic_bloc_by_label(self, label): + def get_basic_block_by_loc_key(self, loc_key): "Return the bbl corresponding to label, None otherwise" - return self.name2bbl.get(self.canonize_label_name(label), None) + return self.name2bbl.get(self.llvm_context.canonize_label_name(loc_key), None) def global_constant(self, name, value): """ @@ -591,11 +570,11 @@ class LLVMFunction(): # Destination builder = self.builder - if isinstance(dst, m2_expr.ExprId): + if isinstance(dst, ExprId): ptr_casted = self.get_ptr_by_expr(dst) builder.store(src, ptr_casted) - elif isinstance(dst, m2_expr.ExprMem): + elif isinstance(dst, ExprMem): addr = self.add_ir(dst.arg) self.llvm_context.memory_write(self, addr, dst.size, src) else: @@ -648,19 +627,18 @@ class LLVMFunction(): builder = self.builder - if isinstance(expr, m2_expr.ExprInt): + if isinstance(expr, ExprInt): ret = llvm_ir.Constant(LLVMType.IntType(expr.size), int(expr.arg)) self.update_cache(expr, ret) return ret - if expr.is_label(): - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(expr.loc_key) - offset = label.offset + if expr.is_loc(): + offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key) ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset) self.update_cache(expr, ret) return ret - if isinstance(expr, m2_expr.ExprId): + if isinstance(expr, ExprId): name = expr.name try: # If expr.name is already known (args) @@ -674,7 +652,7 @@ class LLVMFunction(): self.update_cache(expr, var) return var - if isinstance(expr, m2_expr.ExprOp): + if isinstance(expr, ExprOp): op = expr.op if (op in self.op_translate or @@ -881,12 +859,12 @@ class LLVMFunction(): raise NotImplementedError() - if isinstance(expr, m2_expr.ExprMem): + if isinstance(expr, ExprMem): addr = self.add_ir(expr.arg) return self.llvm_context.memory_lookup(self, addr, expr.size) - if isinstance(expr, m2_expr.ExprCond): + if isinstance(expr, ExprCond): # Compute cond cond = self.add_ir(expr.cond) zero_casted = LLVMType.IntType(expr.cond.size)(0) @@ -899,7 +877,7 @@ class LLVMFunction(): self.update_cache(expr, ret) return ret - if isinstance(expr, m2_expr.ExprSlice): + if isinstance(expr, ExprSlice): src = self.add_ir(expr.arg) @@ -925,7 +903,7 @@ class LLVMFunction(): self.update_cache(expr, ret) return ret - if isinstance(expr, m2_expr.ExprCompose): + if isinstance(expr, ExprCompose): args = [] @@ -1006,9 +984,9 @@ class LLVMFunction(): builder.position_at_end(then_block) PC = self.llvm_context.PC if isinstance(offset, (int, long)): - offset = self.add_ir(m2_expr.ExprInt(offset, PC.size)) + offset = self.add_ir(ExprInt(offset, PC.size)) self.affect(offset, PC) - self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32)) self.set_ret(offset) builder.position_at_end(merge_block) @@ -1053,9 +1031,9 @@ class LLVMFunction(): builder.position_at_end(then_block) PC = self.llvm_context.PC if isinstance(offset, (int, long)): - offset = self.add_ir(m2_expr.ExprInt(offset, PC.size)) + offset = self.add_ir(ExprInt(offset, PC.size)) self.affect(offset, PC) - self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32)) self.set_ret(offset) builder.position_at_end(merge_block) @@ -1100,9 +1078,9 @@ class LLVMFunction(): for i, solution in enumerate(possible_values(expr)): value = solution.value index = dst2case.get(value, i) - to_eval = to_eval.replace_expr({value: m2_expr.ExprInt(index, value.size)}) + to_eval = to_eval.replace_expr({value: ExprInt(index, value.size)}) dst2case[value] = index - if value.is_int() or value.is_label(): + if value.is_int() or value.is_loc(): case2dst[i] = value else: case2dst[i] = self.add_ir(value) @@ -1128,14 +1106,14 @@ class LLVMFunction(): # We are no longer in the main stream, deactivate cache self.main_stream = False - if isinstance(dst, m2_expr.ExprInt): - label = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)) - dst = m2_expr.ExprLoc(label.loc_key, dst.size) + if isinstance(dst, ExprInt): + loc_key = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)) + dst = ExprLoc(loc_key, dst.size) - if isinstance(dst, m2_expr.ExprLoc): - label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(dst.loc_key) - bbl = self.get_basic_bloc_by_label(label) - offset = label.offset + if isinstance(dst, ExprLoc): + loc_key = dst.loc_key + bbl = self.get_basic_block_by_loc_key(loc_key) + offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(loc_key) if bbl is not None: # "local" jump, inside this function if offset is None: @@ -1155,7 +1133,7 @@ class LLVMFunction(): # extern # "extern" jump on a defined offset, return to the caller - dst = self.add_ir(m2_expr.ExprInt(offset, PC.size)) + dst = self.add_ir(ExprInt(offset, PC.size)) # "extern" jump with a computed value, return to the caller assert isinstance(dst, (llvm_ir.Instruction, llvm_ir.Value)) @@ -1167,7 +1145,7 @@ class LLVMFunction(): self.gen_post_code(attrib) self.affect(dst, PC) self.gen_post_instr_checks(attrib, dst) - self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(0, 8)), ExprId("status", 32)) self.set_ret(dst) @@ -1191,7 +1169,7 @@ class LLVMFunction(): # Prefetch memory for element in assignblk.get_r(mem_read=True): - if isinstance(element, m2_expr.ExprMem): + if isinstance(element, ExprMem): self.add_ir(element) # Evaluate expressions @@ -1209,7 +1187,7 @@ class LLVMFunction(): # Update the memory for dst, src in values.iteritems(): - if isinstance(dst, m2_expr.ExprMem): + if isinstance(dst, ExprMem): self.affect(src, dst) # Check memory write exception @@ -1219,7 +1197,7 @@ class LLVMFunction(): # Update registers values for dst, src in values.iteritems(): - if not isinstance(dst, m2_expr.ExprMem): + if not isinstance(dst, ExprMem): self.affect(src, dst) # Check post assignblk exception flags @@ -1260,11 +1238,12 @@ class LLVMFunction(): builder = self.builder m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags t_size = LLVMType.IntType(m2_exception_flag.size) - self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), - m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(1, 8)), + ExprId("status", 32)) self.affect(t_size(m2_csts.EXCEPT_UNK_MNEMO), m2_exception_flag) - self.set_ret(LLVMType.IntType(64)(asmblock.label.offset)) + offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(asmblock.loc_key) + self.set_ret(LLVMType.IntType(64)(offset)) def gen_finalize(self, asmblock, codegen): """ @@ -1275,11 +1254,11 @@ class LLVMFunction(): next_label = codegen.get_block_post_label(asmblock) builder = self.builder - builder.position_at_end(self.get_basic_bloc_by_label(next_label)) + builder.position_at_end(self.get_basic_block_by_loc_key(next_label)) # Common code - self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), - m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(0, 8)), + ExprId("status", 32)) # Check if IRDst has been set zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0) @@ -1302,14 +1281,15 @@ class LLVMFunction(): PC = self.llvm_context.PC to_ret = self.add_ir(codegen.delay_slot_dst) self.affect(to_ret, PC) - self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), - m2_expr.ExprId("status", 32)) + self.affect(self.add_ir(ExprInt(0, 8)), + ExprId("status", 32)) self.set_ret(to_ret) # Else Block builder.position_at_end(else_block) PC = self.llvm_context.PC - to_ret = LLVMType.IntType(PC.size)(next_label.offset) + next_label_offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(next_label) + to_ret = LLVMType.IntType(PC.size)(next_label_offset) self.affect(to_ret, PC) self.set_ret(to_ret) @@ -1318,16 +1298,16 @@ class LLVMFunction(): Prototype : f(i8* jitcpu, i8* vmcpu, i8* vmmngr, i8* status)""" # Build function signature - self.my_args.append((m2_expr.ExprId("jitcpu", 32), + self.my_args.append((ExprId("jitcpu", 32), llvm_ir.PointerType(LLVMType.IntType(8)), "jitcpu")) - self.my_args.append((m2_expr.ExprId("vmcpu", 32), + self.my_args.append((ExprId("vmcpu", 32), llvm_ir.PointerType(LLVMType.IntType(8)), "vmcpu")) - self.my_args.append((m2_expr.ExprId("vmmngr", 32), + self.my_args.append((ExprId("vmmngr", 32), llvm_ir.PointerType(LLVMType.IntType(8)), "vmmngr")) - self.my_args.append((m2_expr.ExprId("status", 32), + self.my_args.append((ExprId("status", 32), llvm_ir.PointerType(LLVMType.IntType(8)), "status")) ret_size = 64 @@ -1360,9 +1340,10 @@ class LLVMFunction(): ptr = self.CreateEntryBlockAlloca(eltype, default_value=eltype(0)) self.local_vars_pointers[element.name] = ptr - lbl = codegen.get_block_post_label(asmblock) - instr_offsets.append(lbl.offset) - self.append_basic_block(lbl) + loc_key = codegen.get_block_post_label(asmblock) + offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(loc_key) + instr_offsets.append(offset) + self.append_basic_block(loc_key) # Add content builder.position_at_end(entry_bbl) @@ -1375,7 +1356,7 @@ class LLVMFunction(): # Pre-create basic blocks for irblock in irblocks: - self.append_basic_block(irblock.label, overwrite=False) + self.append_basic_block(irblock.loc_key, overwrite=False) # Generate the corresponding code for index, irblock in enumerate(irblocks): @@ -1383,8 +1364,7 @@ class LLVMFunction(): irblock, self.llvm_context.ir_arch.attrib) # Set the builder at the begining of the correct bbl - name = self.canonize_label_name(new_irblock.label) - self.builder.position_at_end(self.get_basic_bloc_by_label(name)) + self.builder.position_at_end(self.get_basic_block_by_loc_key(new_irblock.loc_key)) if index == 0: self.gen_pre_code(instr_attrib) @@ -1395,7 +1375,7 @@ class LLVMFunction(): # Branch entry_bbl on first label builder.position_at_end(entry_bbl) - first_label_bbl = self.get_basic_bloc_by_label(asmblock.label) + first_label_bbl = self.get_basic_block_by_loc_key(asmblock.loc_key) builder.branch(first_label_bbl) diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py index ea6c2c98..9bc0ef8b 100644 --- a/miasm2/jitter/loader/pe.py +++ b/miasm2/jitter/loader/pe.py @@ -162,7 +162,9 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs): new_size = pe.SHList[i + 1].addr - section.addr section.size = new_size section.rawsize = new_size - section.data = section.data[:new_size] + section.data = strpatchwork.StrPatchwork( + section.data[:new_size] + ) section.offset = section.addr # Last section alignement diff --git a/test/analysis/data_flow.py b/test/analysis/data_flow.py index 24335f45..c3469109 100644 --- a/test/analysis/data_flow.py +++ b/test/analysis/data_flow.py @@ -1,6 +1,6 @@ """ Test cases for dead code elimination""" from miasm2.expression.expression import ExprId, ExprInt, ExprAff, ExprMem -from miasm2.core.asmblock import AsmLabel, AsmSymbolPool +from miasm2.core.asmblock import AsmSymbolPool from miasm2.analysis.data_flow import * from miasm2.ir.analysis import ira from miasm2.ir.ir import IRBlock, AssignBlock @@ -26,13 +26,13 @@ CST1 = ExprInt(0x11, 32) CST2 = ExprInt(0x12, 32) CST3 = ExprInt(0x13, 32) -LBL0 = symbol_pool.add_label("lbl0", 0) -LBL1 = symbol_pool.add_label("lbl1", 1) -LBL2 = symbol_pool.add_label("lbl2", 2) -LBL3 = symbol_pool.add_label("lbl3", 3) -LBL4 = symbol_pool.add_label("lbl4", 4) -LBL5 = symbol_pool.add_label("lbl5", 5) -LBL6 = symbol_pool.add_label("lbl6", 6) +LBL0 = symbol_pool.add_location("lbl0", 0) +LBL1 = symbol_pool.add_location("lbl1", 1) +LBL2 = symbol_pool.add_location("lbl2", 2) +LBL3 = symbol_pool.add_location("lbl3", 3) +LBL4 = symbol_pool.add_location("lbl4", 4) +LBL5 = symbol_pool.add_location("lbl5", 5) +LBL6 = symbol_pool.add_location("lbl6", 6) IRDst = ExprId('IRDst', 32) dummy = ExprId('dummy', 32) @@ -47,7 +47,7 @@ def gen_irblock(label, exprs_list): irs.append(AssignBlock(exprs)) irs.append(AssignBlock({IRDst:dummy})) - irbl = IRBlock(label.loc_key, irs) + irbl = IRBlock(label, irs) return irbl @@ -85,10 +85,10 @@ G1_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)], [ExprAff(b, CST2)]]) G1_IRB1 = gen_irblock(LBL1, [[ExprAff(a, b)]]) G1_IRB2 = gen_irblock(LBL2, [[ExprAff(r, a)]]) -G1_IRA.blocks = {irb.label : irb for irb in [G1_IRB0, G1_IRB1, G1_IRB2]} +G1_IRA.blocks = {irb.loc_key : irb for irb in [G1_IRB0, G1_IRB1, G1_IRB2]} -G1_IRA.graph.add_uniq_edge(G1_IRB0.label, G1_IRB1.label) -G1_IRA.graph.add_uniq_edge(G1_IRB1.label, G1_IRB2.label) +G1_IRA.graph.add_uniq_edge(G1_IRB0.loc_key, G1_IRB1.loc_key) +G1_IRA.graph.add_uniq_edge(G1_IRB1.loc_key, G1_IRB2.loc_key) # Expected output for graph 1 G1_EXP_IRA = IRATest(symbol_pool) @@ -97,7 +97,7 @@ G1_EXP_IRB0 = gen_irblock(LBL0, [[], [ExprAff(b, CST2)]]) G1_EXP_IRB1 = gen_irblock(LBL1, [[ExprAff(a, b)]]) G1_EXP_IRB2 = gen_irblock(LBL2, [[ExprAff(r, a)]]) -G1_EXP_IRA.blocks = {irb.label : irb for irb in [G1_EXP_IRB0, G1_EXP_IRB1, +G1_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G1_EXP_IRB0, G1_EXP_IRB1, G1_EXP_IRB2]} # graph 2 : Natural loop with dead variable @@ -108,11 +108,11 @@ G2_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)], [ExprAff(r, CST1)]]) G2_IRB1 = gen_irblock(LBL1, [[ExprAff(a, a+CST1)]]) G2_IRB2 = gen_irblock(LBL2, [[ExprAff(a, r)]]) -G2_IRA.blocks = {irb.label : irb for irb in [G2_IRB0, G2_IRB1, G2_IRB2]} +G2_IRA.blocks = {irb.loc_key : irb for irb in [G2_IRB0, G2_IRB1, G2_IRB2]} -G2_IRA.graph.add_uniq_edge(G2_IRB0.label, G2_IRB1.label) -G2_IRA.graph.add_uniq_edge(G2_IRB1.label, G2_IRB2.label) -G2_IRA.graph.add_uniq_edge(G2_IRB1.label, G2_IRB1.label) +G2_IRA.graph.add_uniq_edge(G2_IRB0.loc_key, G2_IRB1.loc_key) +G2_IRA.graph.add_uniq_edge(G2_IRB1.loc_key, G2_IRB2.loc_key) +G2_IRA.graph.add_uniq_edge(G2_IRB1.loc_key, G2_IRB1.loc_key) # Expected output for graph 2 G2_EXP_IRA = IRATest(symbol_pool) @@ -121,7 +121,7 @@ G2_EXP_IRB0 = gen_irblock(LBL0, [[], [ExprAff(r, CST1)]]) G2_EXP_IRB1 = gen_irblock(LBL1, [[]]) G2_EXP_IRB2 = gen_irblock(LBL2, [[]]) -G2_EXP_IRA.blocks = {irb.label : irb for irb in [G2_EXP_IRB0, G2_EXP_IRB1, +G2_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G2_EXP_IRB0, G2_EXP_IRB1, G2_EXP_IRB2]} # graph 3 : Natural loop with alive variables @@ -132,11 +132,11 @@ G3_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)]]) G3_IRB1 = gen_irblock(LBL1, [[ExprAff(a, a+CST1)]]) G3_IRB2 = gen_irblock(LBL2, [[ExprAff(r, a)]]) -G3_IRA.blocks = {irb.label : irb for irb in [G3_IRB0, G3_IRB1, G3_IRB2]} +G3_IRA.blocks = {irb.loc_key : irb for irb in [G3_IRB0, G3_IRB1, G3_IRB2]} -G3_IRA.graph.add_uniq_edge(G3_IRB0.label, G3_IRB1.label) -G3_IRA.graph.add_uniq_edge(G3_IRB1.label, G3_IRB2.label) -G3_IRA.graph.add_uniq_edge(G3_IRB1.label, G3_IRB1.label) +G3_IRA.graph.add_uniq_edge(G3_IRB0.loc_key, G3_IRB1.loc_key) +G3_IRA.graph.add_uniq_edge(G3_IRB1.loc_key, G3_IRB2.loc_key) +G3_IRA.graph.add_uniq_edge(G3_IRB1.loc_key, G3_IRB1.loc_key) # Expected output for graph 3 G3_EXP_IRA = IRATest(symbol_pool) @@ -145,7 +145,7 @@ G3_EXP_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)]]) G3_EXP_IRB1 = gen_irblock(LBL1, [[ExprAff(a, a+CST1)]]) G3_EXP_IRB2 = gen_irblock(LBL2, [[ExprAff(r, a)]]) -G3_EXP_IRA.blocks = {irb.label : irb for irb in [G3_EXP_IRB0, G3_EXP_IRB1, +G3_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G3_EXP_IRB0, G3_EXP_IRB1, G3_EXP_IRB2]} # graph 4 : If/else with dead variables @@ -157,13 +157,13 @@ G4_IRB1 = gen_irblock(LBL1, [[ExprAff(a, a+CST1)]]) G4_IRB2 = gen_irblock(LBL2, [[ExprAff(a, a+CST2)]]) G4_IRB3 = gen_irblock(LBL3, [[ExprAff(a, CST3)], [ExprAff(r, a)]]) -G4_IRA.blocks = {irb.label : irb for irb in [G4_IRB0, G4_IRB1, G4_IRB2, +G4_IRA.blocks = {irb.loc_key : irb for irb in [G4_IRB0, G4_IRB1, G4_IRB2, G4_IRB3]} -G4_IRA.graph.add_uniq_edge(G4_IRB0.label, G4_IRB1.label) -G4_IRA.graph.add_uniq_edge(G4_IRB0.label, G4_IRB2.label) -G4_IRA.graph.add_uniq_edge(G4_IRB1.label, G4_IRB3.label) -G4_IRA.graph.add_uniq_edge(G4_IRB2.label, G4_IRB3.label) +G4_IRA.graph.add_uniq_edge(G4_IRB0.loc_key, G4_IRB1.loc_key) +G4_IRA.graph.add_uniq_edge(G4_IRB0.loc_key, G4_IRB2.loc_key) +G4_IRA.graph.add_uniq_edge(G4_IRB1.loc_key, G4_IRB3.loc_key) +G4_IRA.graph.add_uniq_edge(G4_IRB2.loc_key, G4_IRB3.loc_key) # Expected output for graph 4 G4_EXP_IRA = IRATest(symbol_pool) @@ -173,7 +173,7 @@ G4_EXP_IRB1 = gen_irblock(LBL1, [[]]) G4_EXP_IRB2 = gen_irblock(LBL2, [[]]) G4_EXP_IRB3 = gen_irblock(LBL3, [[ExprAff(a, CST3)], [ExprAff(r, a)]]) -G4_EXP_IRA.blocks = {irb.label : irb for irb in [G4_EXP_IRB0, G4_EXP_IRB1, +G4_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G4_EXP_IRB0, G4_EXP_IRB1, G4_EXP_IRB2, G4_EXP_IRB3]} # graph 5 : Loop and If/else with dead variables @@ -187,16 +187,16 @@ G5_IRB3 = gen_irblock(LBL3, [[ExprAff(a, a+CST3)]]) G5_IRB4 = gen_irblock(LBL4, [[ExprAff(a, a+CST1)]]) G5_IRB5 = gen_irblock(LBL5, [[ExprAff(a, r)]]) -G5_IRA.blocks = {irb.label : irb for irb in [G5_IRB0, G5_IRB1, G5_IRB2, G5_IRB3, +G5_IRA.blocks = {irb.loc_key : irb for irb in [G5_IRB0, G5_IRB1, G5_IRB2, G5_IRB3, G5_IRB4, G5_IRB5]} -G5_IRA.graph.add_uniq_edge(G5_IRB0.label, G5_IRB1.label) -G5_IRA.graph.add_uniq_edge(G5_IRB1.label, G5_IRB2.label) -G5_IRA.graph.add_uniq_edge(G5_IRB1.label, G5_IRB3.label) -G5_IRA.graph.add_uniq_edge(G5_IRB2.label, G5_IRB4.label) -G5_IRA.graph.add_uniq_edge(G5_IRB3.label, G5_IRB4.label) -G5_IRA.graph.add_uniq_edge(G5_IRB4.label, G5_IRB5.label) -G5_IRA.graph.add_uniq_edge(G5_IRB4.label, G5_IRB1.label) +G5_IRA.graph.add_uniq_edge(G5_IRB0.loc_key, G5_IRB1.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB1.loc_key, G5_IRB2.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB1.loc_key, G5_IRB3.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB2.loc_key, G5_IRB4.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB3.loc_key, G5_IRB4.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB4.loc_key, G5_IRB5.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB4.loc_key, G5_IRB1.loc_key) # Expected output for graph 5 G5_EXP_IRA = IRATest(symbol_pool) @@ -208,7 +208,7 @@ G5_EXP_IRB3 = gen_irblock(LBL3, [[]]) G5_EXP_IRB4 = gen_irblock(LBL4, [[]]) G5_EXP_IRB5 = gen_irblock(LBL5, [[]]) -G5_EXP_IRA.blocks = {irb.label : irb for irb in [G5_EXP_IRB0, G5_EXP_IRB1, +G5_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G5_EXP_IRB0, G5_EXP_IRB1, G5_EXP_IRB2, G5_EXP_IRB3, G5_EXP_IRB4, G5_EXP_IRB5]} @@ -222,13 +222,13 @@ G6_IRB1 = gen_irblock(LBL1, [[ExprAff(b, a)]]) G6_IRB2 = gen_irblock(LBL2, [[ExprAff(a, b)]]) G6_IRB3 = gen_irblock(LBL3, [[ExprAff(r, CST2)]]) -G6_IRA.blocks = {irb.label : irb for irb in [G6_IRB0, G6_IRB1, G6_IRB2, +G6_IRA.blocks = {irb.loc_key : irb for irb in [G6_IRB0, G6_IRB1, G6_IRB2, G6_IRB3]} -G6_IRA.graph.add_uniq_edge(G6_IRB0.label, G6_IRB1.label) -G6_IRA.graph.add_uniq_edge(G6_IRB1.label, G6_IRB2.label) -G6_IRA.graph.add_uniq_edge(G6_IRB2.label, G6_IRB1.label) -G6_IRA.graph.add_uniq_edge(G6_IRB2.label, G6_IRB3.label) +G6_IRA.graph.add_uniq_edge(G6_IRB0.loc_key, G6_IRB1.loc_key) +G6_IRA.graph.add_uniq_edge(G6_IRB1.loc_key, G6_IRB2.loc_key) +G6_IRA.graph.add_uniq_edge(G6_IRB2.loc_key, G6_IRB1.loc_key) +G6_IRA.graph.add_uniq_edge(G6_IRB2.loc_key, G6_IRB3.loc_key) # Expected output for graph 6 G6_EXP_IRA = IRATest(symbol_pool) @@ -238,7 +238,7 @@ G6_EXP_IRB1 = gen_irblock(LBL1, [[]]) G6_EXP_IRB2 = gen_irblock(LBL2, [[]]) G6_EXP_IRB3 = gen_irblock(LBL3, [[ExprAff(r, CST2)]]) -G6_EXP_IRA.blocks = {irb.label : irb for irb in [G6_EXP_IRB0, G6_EXP_IRB1, +G6_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G6_EXP_IRB0, G6_EXP_IRB1, G6_EXP_IRB2, G6_EXP_IRB3]} # graph 7 : Double entry loop with dead variables @@ -250,14 +250,14 @@ G7_IRB1 = gen_irblock(LBL1, [[ExprAff(a, a+CST1)]]) G7_IRB2 = gen_irblock(LBL2, [[ExprAff(a, a+CST2)]]) G7_IRB3 = gen_irblock(LBL3, [[ExprAff(a, r)]]) -G7_IRA.blocks = {irb.label : irb for irb in [G7_IRB0, G7_IRB1, G7_IRB2, +G7_IRA.blocks = {irb.loc_key : irb for irb in [G7_IRB0, G7_IRB1, G7_IRB2, G7_IRB3]} -G7_IRA.graph.add_uniq_edge(G7_IRB0.label, G7_IRB1.label) -G7_IRA.graph.add_uniq_edge(G7_IRB1.label, G7_IRB2.label) -G7_IRA.graph.add_uniq_edge(G7_IRB2.label, G7_IRB1.label) -G7_IRA.graph.add_uniq_edge(G7_IRB2.label, G7_IRB3.label) -G7_IRA.graph.add_uniq_edge(G7_IRB0.label, G7_IRB2.label) +G7_IRA.graph.add_uniq_edge(G7_IRB0.loc_key, G7_IRB1.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB1.loc_key, G7_IRB2.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB2.loc_key, G7_IRB1.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB2.loc_key, G7_IRB3.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB0.loc_key, G7_IRB2.loc_key) # Expected output for graph 7 @@ -268,7 +268,7 @@ G7_EXP_IRB1 = gen_irblock(LBL1, [[]]) G7_EXP_IRB2 = gen_irblock(LBL2, [[]]) G7_EXP_IRB3 = gen_irblock(LBL3, [[]]) -G7_EXP_IRA.blocks = {irb.label : irb for irb in [G7_EXP_IRB0, G7_EXP_IRB1, +G7_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G7_EXP_IRB0, G7_EXP_IRB1, G7_EXP_IRB2, G7_EXP_IRB3]} # graph 8 : Nested loops with dead variables @@ -281,14 +281,14 @@ G8_IRB2 = gen_irblock(LBL2, [[ExprAff(b, b+CST2)]]) G8_IRB3 = gen_irblock(LBL3, [[ExprAff(a, b)]]) -G8_IRA.blocks = {irb.label : irb for irb in [G8_IRB0, G8_IRB1, G8_IRB2, +G8_IRA.blocks = {irb.loc_key : irb for irb in [G8_IRB0, G8_IRB1, G8_IRB2, G8_IRB3]} -G8_IRA.graph.add_uniq_edge(G8_IRB0.label, G8_IRB1.label) -G8_IRA.graph.add_uniq_edge(G8_IRB1.label, G8_IRB2.label) -G8_IRA.graph.add_uniq_edge(G8_IRB2.label, G8_IRB1.label) -G8_IRA.graph.add_uniq_edge(G8_IRB2.label, G8_IRB3.label) -G8_IRA.graph.add_uniq_edge(G8_IRB3.label, G8_IRB2.label) +G8_IRA.graph.add_uniq_edge(G8_IRB0.loc_key, G8_IRB1.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB1.loc_key, G8_IRB2.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB2.loc_key, G8_IRB1.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB2.loc_key, G8_IRB3.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB3.loc_key, G8_IRB2.loc_key) # Expected output for graph 8 @@ -300,7 +300,7 @@ G8_EXP_IRB1 = gen_irblock(LBL1, [[]]) G8_EXP_IRB2 = gen_irblock(LBL2, [[]]) G8_EXP_IRB3 = gen_irblock(LBL3, [[]]) -G8_EXP_IRA.blocks = {irb.label : irb for irb in [G8_EXP_IRB0, G8_EXP_IRB1, +G8_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G8_EXP_IRB0, G8_EXP_IRB1, G8_EXP_IRB2, G8_EXP_IRB3]} # graph 9 : Miultiple-exits loops with dead variables @@ -313,17 +313,17 @@ G9_IRB2 = gen_irblock(LBL2, [[ExprAff(a, a+CST2)], [ExprAff(b, b+CST2)]]) G9_IRB3 = gen_irblock(LBL3, [[ExprAff(a, b)]]) G9_IRB4 = gen_irblock(LBL4, [[ExprAff(r, a)], [ExprAff(r, b)]]) -G9_IRA.blocks = {irb.label : irb for irb in [G9_IRB0, G9_IRB1, G9_IRB2, +G9_IRA.blocks = {irb.loc_key : irb for irb in [G9_IRB0, G9_IRB1, G9_IRB2, G9_IRB3, G9_IRB4]} -G9_IRA.graph.add_uniq_edge(G9_IRB0.label, G9_IRB4.label) -G9_IRA.graph.add_uniq_edge(G9_IRB0.label, G9_IRB1.label) -G9_IRA.graph.add_uniq_edge(G9_IRB1.label, G9_IRB0.label) -G9_IRA.graph.add_uniq_edge(G9_IRB1.label, G9_IRB4.label) -G9_IRA.graph.add_uniq_edge(G9_IRB1.label, G9_IRB2.label) -G9_IRA.graph.add_uniq_edge(G9_IRB2.label, G9_IRB0.label) -G9_IRA.graph.add_uniq_edge(G9_IRB2.label, G9_IRB3.label) -G9_IRA.graph.add_uniq_edge(G9_IRB3.label, G9_IRB4.label) +G9_IRA.graph.add_uniq_edge(G9_IRB0.loc_key, G9_IRB4.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB0.loc_key, G9_IRB1.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB1.loc_key, G9_IRB0.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB1.loc_key, G9_IRB4.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB1.loc_key, G9_IRB2.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB2.loc_key, G9_IRB0.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB2.loc_key, G9_IRB3.loc_key) +G9_IRA.graph.add_uniq_edge(G9_IRB3.loc_key, G9_IRB4.loc_key) # Expected output for graph 9 @@ -336,7 +336,7 @@ G9_EXP_IRB2 = gen_irblock(LBL2, [[], [ExprAff(b, b+CST2)]]) G9_EXP_IRB3 = gen_irblock(LBL3, [[]]) G9_EXP_IRB4 = gen_irblock(LBL4, [[], [ExprAff(r, b)]]) -G9_EXP_IRA.blocks = {irb.label : irb for irb in [G9_EXP_IRB0, G9_EXP_IRB1, +G9_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G9_EXP_IRB0, G9_EXP_IRB1, G9_EXP_IRB2, G9_EXP_IRB3, G9_EXP_IRB4]} @@ -350,13 +350,13 @@ G10_IRB1 = gen_irblock(LBL1, [[ExprAff(b, a)]]) G10_IRB2 = gen_irblock(LBL2, [[ExprAff(a, b)]]) G10_IRB3 = gen_irblock(LBL3, [[ExprAff(r, CST1)]]) -G10_IRA.blocks = {irb.label : irb for irb in [G10_IRB0, G10_IRB1, +G10_IRA.blocks = {irb.loc_key : irb for irb in [G10_IRB0, G10_IRB1, G10_IRB2, G10_IRB3]} -G10_IRA.graph.add_uniq_edge(G10_IRB0.label, G10_IRB1.label) -G10_IRA.graph.add_uniq_edge(G10_IRB1.label, G10_IRB2.label) -G10_IRA.graph.add_uniq_edge(G10_IRB2.label, G10_IRB1.label) -G10_IRA.graph.add_uniq_edge(G10_IRB2.label, G10_IRB3.label) +G10_IRA.graph.add_uniq_edge(G10_IRB0.loc_key, G10_IRB1.loc_key) +G10_IRA.graph.add_uniq_edge(G10_IRB1.loc_key, G10_IRB2.loc_key) +G10_IRA.graph.add_uniq_edge(G10_IRB2.loc_key, G10_IRB1.loc_key) +G10_IRA.graph.add_uniq_edge(G10_IRB2.loc_key, G10_IRB3.loc_key) # Expected output for graph 10 G10_EXP_IRA = IRATest(symbol_pool) @@ -366,7 +366,7 @@ G10_EXP_IRB1 = gen_irblock(LBL1, [[]]) G10_EXP_IRB2 = gen_irblock(LBL2, [[]]) G10_EXP_IRB3 = gen_irblock(LBL3, [[ExprAff(r, CST1)]]) -G10_EXP_IRA.blocks = {irb.label : irb for irb in [G10_EXP_IRB0, G10_EXP_IRB1, +G10_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G10_EXP_IRB0, G10_EXP_IRB1, G10_EXP_IRB2, G10_EXP_IRB3]} # graph 11 : If/Else conditions with alive variables @@ -380,13 +380,13 @@ G11_IRB3 = gen_irblock(LBL3, [[ExprAff(a, a+CST1)]]) G11_IRB4 = gen_irblock(LBL4, [[ExprAff(b, b+CST1)]]) -G11_IRA.blocks = {irb.label : irb for irb in [G11_IRB0, G11_IRB1, G11_IRB2]} +G11_IRA.blocks = {irb.loc_key : irb for irb in [G11_IRB0, G11_IRB1, G11_IRB2]} -G11_IRA.graph.add_uniq_edge(G11_IRB0.label, G11_IRB1.label) -#G11_IRA.graph.add_uniq_edge(G11_IRB3.label, G11_IRB1.label) -G11_IRA.graph.add_uniq_edge(G11_IRB1.label, G11_IRB0.label) -#G11_IRA.graph.add_uniq_edge(G11_IRB4.label, G11_IRB0.label) -G11_IRA.graph.add_uniq_edge(G11_IRB1.label, G11_IRB2.label) +G11_IRA.graph.add_uniq_edge(G11_IRB0.loc_key, G11_IRB1.loc_key) +#G11_IRA.graph.add_uniq_edge(G11_IRB3.loc_key, G11_IRB1.loc_key) +G11_IRA.graph.add_uniq_edge(G11_IRB1.loc_key, G11_IRB0.loc_key) +#G11_IRA.graph.add_uniq_edge(G11_IRB4.loc_key, G11_IRB0.loc_key) +G11_IRA.graph.add_uniq_edge(G11_IRB1.loc_key, G11_IRB2.loc_key) # Expected output for graph 11 @@ -398,7 +398,7 @@ G11_EXP_IRB2 = gen_irblock(LBL2, [[ExprAff(r, a)]]) #G11_EXP_IRB3 = gen_irblock(LBL3, [[ExprAff(a, a+CST1)]]) #G11_EXP_IRB4 = gen_irblock(LBL4, [[ExprAff(b, b+CST1)]]) -G11_EXP_IRA.blocks = {irb.label : irb for irb in [G11_EXP_IRB0, G11_EXP_IRB1, +G11_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G11_EXP_IRB0, G11_EXP_IRB1, G11_EXP_IRB2]} # graph 12 : Graph with multiple out points and useless definitions @@ -413,14 +413,14 @@ G12_IRB3 = gen_irblock(LBL3, [[ExprAff(r, CST3)]]) G12_IRB4 = gen_irblock(LBL4, [[ExprAff(r, CST2)]]) G12_IRB5 = gen_irblock(LBL5, [[ExprAff(r, b)]]) -G12_IRA.blocks = {irb.label : irb for irb in [G12_IRB0, G12_IRB1, G12_IRB2, +G12_IRA.blocks = {irb.loc_key : irb for irb in [G12_IRB0, G12_IRB1, G12_IRB2, G12_IRB3, G12_IRB4, G12_IRB5]} -G12_IRA.graph.add_uniq_edge(G12_IRB0.label, G12_IRB1.label) -G12_IRA.graph.add_uniq_edge(G12_IRB0.label, G12_IRB2.label) -G12_IRA.graph.add_uniq_edge(G12_IRB2.label, G12_IRB3.label) -G12_IRA.graph.add_uniq_edge(G12_IRB2.label, G12_IRB4.label) -G12_IRA.graph.add_uniq_edge(G12_IRB4.label, G12_IRB5.label) +G12_IRA.graph.add_uniq_edge(G12_IRB0.loc_key, G12_IRB1.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB0.loc_key, G12_IRB2.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB2.loc_key, G12_IRB3.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB2.loc_key, G12_IRB4.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB4.loc_key, G12_IRB5.loc_key) # Expected output for graph 12 G12_EXP_IRA = IRATest(symbol_pool) @@ -433,7 +433,7 @@ G12_EXP_IRB4 = gen_irblock(LBL4, [[]]) G12_EXP_IRB5 = gen_irblock(LBL5, [[ExprAff(r, b)]]) -G12_EXP_IRA.blocks = {irb.label : irb for irb in [G12_EXP_IRB0, G12_EXP_IRB1, +G12_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G12_EXP_IRB0, G12_EXP_IRB1, G12_EXP_IRB2, G12_EXP_IRB3, G12_EXP_IRB4, G12_EXP_IRB5]} @@ -448,13 +448,13 @@ G13_IRB2 = gen_irblock(LBL2, [[ExprAff(d, CST2)], [ExprAff(a, b+CST1), G13_IRB3 = gen_irblock(LBL3, [[]]) # lost son G13_IRB4 = gen_irblock(LBL4, [[ExprAff(b, CST2)]]) -G13_IRA.blocks = {irb.label : irb for irb in [G13_IRB0, G13_IRB1, G13_IRB2, +G13_IRA.blocks = {irb.loc_key : irb for irb in [G13_IRB0, G13_IRB1, G13_IRB2, G13_IRB4]} -G13_IRA.graph.add_uniq_edge(G13_IRB0.label, G13_IRB1.label) -G13_IRA.graph.add_uniq_edge(G13_IRB0.label, G13_IRB4.label) -G13_IRA.graph.add_uniq_edge(G13_IRB2.label, G13_IRB3.label) -G13_IRA.graph.add_uniq_edge(G13_IRB4.label, G13_IRB2.label) +G13_IRA.graph.add_uniq_edge(G13_IRB0.loc_key, G13_IRB1.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB0.loc_key, G13_IRB4.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB2.loc_key, G13_IRB3.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB4.loc_key, G13_IRB2.loc_key) # Expected output for graph 13 G13_EXP_IRA = IRATest(symbol_pool) @@ -466,7 +466,7 @@ G13_EXP_IRB2 = gen_irblock(LBL2, [[ExprAff(d, CST2)], [ExprAff(a, b+CST1), G13_EXP_IRB3 = gen_irblock(LBL3, [[]]) G13_EXP_IRB4 = gen_irblock(LBL4, [[ExprAff(b, CST2)]]) -G13_EXP_IRA.blocks = {irb.label: irb for irb in [G13_EXP_IRB0, G13_EXP_IRB1, +G13_EXP_IRA.blocks = {irb.loc_key: irb for irb in [G13_EXP_IRB0, G13_EXP_IRB1, G13_EXP_IRB2, G13_EXP_IRB4]} #G13_EXP_IRA = G13_IRA @@ -480,9 +480,9 @@ G14_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)], [ExprAff(c, a)], [ExprAff(a, CST2)]]) G14_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a+c)]]) -G14_IRA.blocks = {irb.label : irb for irb in [G14_IRB0, G14_IRB1]} +G14_IRA.blocks = {irb.loc_key : irb for irb in [G14_IRB0, G14_IRB1]} -G14_IRA.graph.add_uniq_edge(G14_IRB0.label, G14_IRB1.label) +G14_IRA.graph.add_uniq_edge(G14_IRB0.loc_key, G14_IRB1.loc_key) # Expected output for graph 1 G14_EXP_IRA = IRATest(symbol_pool) @@ -491,7 +491,7 @@ G14_EXP_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1)], [ExprAff(c, a)], [ExprAff(a, CST2)]]) G14_EXP_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a+c)]]) -G14_EXP_IRA.blocks = {irb.label: irb for irb in [G14_EXP_IRB0, G14_EXP_IRB1]} +G14_EXP_IRA.blocks = {irb.loc_key: irb for irb in [G14_EXP_IRB0, G14_EXP_IRB1]} # graph 15 : Graph where variable assigned multiple and read at the same time, # but useless @@ -503,9 +503,9 @@ G15_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST2)], [ExprAff(a, CST1), ExprAff(c, CST1)]]) G15_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a)]]) -G15_IRA.blocks = {irb.label : irb for irb in [G15_IRB0, G15_IRB1]} +G15_IRA.blocks = {irb.loc_key : irb for irb in [G15_IRB0, G15_IRB1]} -G15_IRA.graph.add_uniq_edge(G15_IRB0.label, G15_IRB1.label) +G15_IRA.graph.add_uniq_edge(G15_IRB0.loc_key, G15_IRB1.loc_key) # Expected output for graph 1 G15_EXP_IRA = IRATest(symbol_pool) @@ -513,7 +513,7 @@ G15_EXP_IRA = IRATest(symbol_pool) G15_EXP_IRB0 = gen_irblock(LBL0, [[], [ExprAff(a, CST1)]]) G15_EXP_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a)]]) -G15_EXP_IRA.blocks = {irb.label: irb for irb in [G15_EXP_IRB0, G15_EXP_IRB1]} +G15_EXP_IRA.blocks = {irb.loc_key: irb for irb in [G15_EXP_IRB0, G15_EXP_IRB1]} # graph 16 : Graph where variable assigned multiple times in the same bloc @@ -525,12 +525,12 @@ G16_IRB0 = gen_irblock(LBL0, [[ExprAff(a, CST1), ExprAff(b, CST2), G16_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a+b)], [ExprAff(r, c+r)]]) G16_IRB2 = gen_irblock(LBL2, [[]]) -G16_IRA.blocks = {irb.label : irb for irb in [G16_IRB0, G16_IRB1]} +G16_IRA.blocks = {irb.loc_key : irb for irb in [G16_IRB0, G16_IRB1]} -G16_IRA.graph.add_uniq_edge(G16_IRB0.label, G16_IRB1.label) -G16_IRA.graph.add_uniq_edge(G16_IRB1.label, G16_IRB2.label) +G16_IRA.graph.add_uniq_edge(G16_IRB0.loc_key, G16_IRB1.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB1.loc_key, G16_IRB2.loc_key) -G16_IRA.blocks = {irb.label : irb for irb in [G16_IRB0, G16_IRB1]} +G16_IRA.blocks = {irb.loc_key : irb for irb in [G16_IRB0, G16_IRB1]} # Expected output for graph 1 G16_EXP_IRA = IRATest(symbol_pool) @@ -539,7 +539,7 @@ G16_EXP_IRB0 = gen_irblock(LBL0, [[ExprAff(c, CST3)], [ExprAff(a, c + CST1), ExprAff(b, c + CST2)]]) G16_EXP_IRB1 = gen_irblock(LBL1, [[ExprAff(r, a+b)], [ExprAff(r, c+r)]]) -G16_EXP_IRA.blocks = {irb.label: irb for irb in [G16_EXP_IRB0, G16_EXP_IRB1]} +G16_EXP_IRA.blocks = {irb.loc_key: irb for irb in [G16_EXP_IRB0, G16_EXP_IRB1]} # graph 17 : parallel ir @@ -599,9 +599,9 @@ G17_IRB0 = gen_irblock(LBL0, [[ExprAff(a, a*b), ]) -G17_IRA.blocks = {irb.label : irb for irb in [G17_IRB0]} +G17_IRA.blocks = {irb.loc_key : irb for irb in [G17_IRB0]} -G17_IRA.graph.add_node(G17_IRB0.label) +G17_IRA.graph.add_node(G17_IRB0.loc_key) # Expected output for graph 17 G17_EXP_IRA = IRATest(symbol_pool) @@ -641,7 +641,7 @@ G17_EXP_IRB0 = gen_irblock(LBL0, [[], # Trick because a+b+c != ((a+b)+c) ]) -G17_EXP_IRA.blocks = {irb.label : irb for irb in [G17_EXP_IRB0]} +G17_EXP_IRA.blocks = {irb.loc_key : irb for irb in [G17_EXP_IRB0]} # Begining of tests diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py index 545269e7..4e023761 100644 --- a/test/analysis/depgraph.py +++ b/test/analysis/depgraph.py @@ -1,6 +1,7 @@ """Regression test module for DependencyGraph""" -from miasm2.expression.expression import ExprId, ExprInt, ExprAff, ExprCond, ExprLoc -from miasm2.core.asmblock import AsmLabel, AsmSymbolPool +from miasm2.expression.expression import ExprId, ExprInt, ExprAff, ExprCond, \ + ExprLoc, LocKey +from miasm2.core.asmblock import AsmSymbolPool from miasm2.ir.analysis import ira from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.core.graph import DiGraph @@ -43,13 +44,13 @@ CST33 = ExprInt(0x33, 32) CST35 = ExprInt(0x35, 32) CST37 = ExprInt(0x37, 32) -LBL0 = symbol_pool.add_label("lbl0", 0) -LBL1 = symbol_pool.add_label("lbl1", 1) -LBL2 = symbol_pool.add_label("lbl2", 2) -LBL3 = symbol_pool.add_label("lbl3", 3) -LBL4 = symbol_pool.add_label("lbl4", 4) -LBL5 = symbol_pool.add_label("lbl5", 5) -LBL6 = symbol_pool.add_label("lbl6", 6) +LBL0 = symbol_pool.add_location("lbl0", 0) +LBL1 = symbol_pool.add_location("lbl1", 1) +LBL2 = symbol_pool.add_location("lbl2", 2) +LBL3 = symbol_pool.add_location("lbl3", 3) +LBL4 = symbol_pool.add_location("lbl4", 4) +LBL5 = symbol_pool.add_location("lbl5", 5) +LBL6 = symbol_pool.add_location("lbl6", 6) def gen_irblock(label, exprs_list): """ Returns an IRBlock. @@ -62,7 +63,7 @@ def gen_irblock(label, exprs_list): else: irs.append(AssignBlock(exprs)) - irbl = IRBlock(label.loc_key, irs) + irbl = IRBlock(label, irs) return irbl @@ -114,8 +115,8 @@ def bloc2graph(irgraph, label=False, lines=True): # Generate basic blocks out_blocks = [] for label in irgraph.graph.nodes(): - if isinstance(label, AsmLabel): - label_name = label.name + if isinstance(label, LocKey): + label_name = irgraph.symbol_pool.loc_key_to_name(label) else: label_name = str(label) @@ -123,8 +124,8 @@ def bloc2graph(irgraph, label=False, lines=True): irblock = irgraph.blocks[label] else: irblock = None - if isinstance(label, AsmLabel): - out_block = '%s [\n' % label.name + if isinstance(label, LocKey): + out_block = '%s [\n' % label_name else: out_block = '%s [\n' % label out_block += "%s " % block_attr @@ -154,12 +155,12 @@ def bloc2graph(irgraph, label=False, lines=True): out += out_blocks # Generate links for src, dst in irgraph.graph.edges(): - if isinstance(src, AsmLabel): - src_name = src.name + if isinstance(src, LocKey): + src_name = irgraph.symbol_pool.loc_key_to_name(src) else: src_name = str(src) - if isinstance(dst, AsmLabel): - dst_name = dst.name + if isinstance(dst, LocKey): + dst_name = irgraph.symbol_pool.loc_key_to_name(dst) else: dst_name = str(dst) @@ -186,20 +187,20 @@ def dg2graph(graph, label=False, lines=True): # Generate basic blocks out_blocks = [] - for label in graph.nodes(): - if isinstance(label, DependencyNode): - lbl = symbol_pool.loc_key_to_label(label.label) - label_name = "%s %s %s" % (lbl.name, - label.element, - label.line_nb) + for node in graph.nodes(): + if isinstance(node, DependencyNode): + name = symbol_pool.loc_key_to_name(node.loc_key) + node_name = "%s %s %s" % (name, + node.element, + node.line_nb) else: - label_name = str(label) - out_block = '%s [\n' % hash(label) + node_name = str(node) + out_block = '%s [\n' % hash(node) out_block += "%s " % block_attr out_block += 'label =<<table border="0" cellborder="0" cellpadding="3">' block_label = '<tr><td %s>%s</td></tr>' % ( - label_attr, label_name) + label_attr, node_name) block_html_lines = [] block_html_lines = ('<tr><td %s>' % td_attr + ('</td></tr><tr><td %s>' % td_attr).join(block_html_lines) + @@ -237,10 +238,10 @@ G1_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]]) G1_IRB1 = gen_irblock(LBL1, [[ExprAff(B, C)]]) G1_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]]) -G1_IRA.graph.add_uniq_edge(G1_IRB0.label, G1_IRB1.label) -G1_IRA.graph.add_uniq_edge(G1_IRB1.label, G1_IRB2.label) +G1_IRA.graph.add_uniq_edge(G1_IRB0.loc_key, G1_IRB1.loc_key) +G1_IRA.graph.add_uniq_edge(G1_IRB1.loc_key, G1_IRB2.loc_key) -G1_IRA.blocks = dict([(irb.label, irb) for irb in [G1_IRB0, G1_IRB1, G1_IRB2]]) +G1_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G1_IRB0, G1_IRB1, G1_IRB2]]) # graph 2 @@ -250,10 +251,10 @@ G2_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]]) G2_IRB1 = gen_irblock(LBL1, [[ExprAff(B, CST2)]]) G2_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B + C)]]) -G2_IRA.graph.add_uniq_edge(G2_IRB0.label, G2_IRB1.label) -G2_IRA.graph.add_uniq_edge(G2_IRB1.label, G2_IRB2.label) +G2_IRA.graph.add_uniq_edge(G2_IRB0.loc_key, G2_IRB1.loc_key) +G2_IRA.graph.add_uniq_edge(G2_IRB1.loc_key, G2_IRB2.loc_key) -G2_IRA.blocks = dict([(irb.label, irb) for irb in [G2_IRB0, G2_IRB1, G2_IRB2]]) +G2_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G2_IRB0, G2_IRB1, G2_IRB2]]) # graph 3 @@ -265,12 +266,12 @@ G3_IRB1 = gen_irblock(LBL1, [[ExprAff(B, CST2)]]) G3_IRB2 = gen_irblock(LBL2, [[ExprAff(B, CST3)]]) G3_IRB3 = gen_irblock(LBL3, [[ExprAff(A, B + C)]]) -G3_IRA.graph.add_uniq_edge(G3_IRB0.label, G3_IRB1.label) -G3_IRA.graph.add_uniq_edge(G3_IRB0.label, G3_IRB2.label) -G3_IRA.graph.add_uniq_edge(G3_IRB1.label, G3_IRB3.label) -G3_IRA.graph.add_uniq_edge(G3_IRB2.label, G3_IRB3.label) +G3_IRA.graph.add_uniq_edge(G3_IRB0.loc_key, G3_IRB1.loc_key) +G3_IRA.graph.add_uniq_edge(G3_IRB0.loc_key, G3_IRB2.loc_key) +G3_IRA.graph.add_uniq_edge(G3_IRB1.loc_key, G3_IRB3.loc_key) +G3_IRA.graph.add_uniq_edge(G3_IRB2.loc_key, G3_IRB3.loc_key) -G3_IRA.blocks = dict([(irb.label, irb) for irb in [G3_IRB0, G3_IRB1, +G3_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G3_IRB0, G3_IRB1, G3_IRB2, G3_IRB3]]) # graph 4 @@ -280,16 +281,16 @@ G4_IRA = IRATest(symbol_pool) G4_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]]) G4_IRB1 = gen_irblock(LBL1, [[ExprAff(C, C + CST2)], [ExprAff(G4_IRA.IRDst, - ExprCond(C, ExprLoc(LBL2.loc_key, 32), - ExprLoc(LBL1.loc_key, 32)))]]) + ExprCond(C, ExprLoc(LBL2, 32), + ExprLoc(LBL1, 32)))]]) G4_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]]) -G4_IRA.graph.add_uniq_edge(G4_IRB0.label, G4_IRB1.label) -G4_IRA.graph.add_uniq_edge(G4_IRB1.label, G4_IRB2.label) -G4_IRA.graph.add_uniq_edge(G4_IRB1.label, G4_IRB1.label) +G4_IRA.graph.add_uniq_edge(G4_IRB0.loc_key, G4_IRB1.loc_key) +G4_IRA.graph.add_uniq_edge(G4_IRB1.loc_key, G4_IRB2.loc_key) +G4_IRA.graph.add_uniq_edge(G4_IRB1.loc_key, G4_IRB1.loc_key) -G4_IRA.blocks = dict([(irb.label, irb) for irb in [G4_IRB0, G4_IRB1, G4_IRB2]]) +G4_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G4_IRB0, G4_IRB1, G4_IRB2]]) # graph 5 @@ -299,16 +300,16 @@ G5_IRA = IRATest(symbol_pool) G5_IRB0 = gen_irblock(LBL0, [[ExprAff(B, CST1)]]) G5_IRB1 = gen_irblock(LBL1, [[ExprAff(B, B + CST2)], [ExprAff(G5_IRA.IRDst, - ExprCond(B, ExprLoc(LBL2.loc_key, 32), - ExprLoc(LBL1.loc_key, 32)))]]) + ExprCond(B, ExprLoc(LBL2, 32), + ExprLoc(LBL1, 32)))]]) G5_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]]) -G5_IRA.graph.add_uniq_edge(G5_IRB0.label, G5_IRB1.label) -G5_IRA.graph.add_uniq_edge(G5_IRB1.label, G5_IRB2.label) -G5_IRA.graph.add_uniq_edge(G5_IRB1.label, G5_IRB1.label) +G5_IRA.graph.add_uniq_edge(G5_IRB0.loc_key, G5_IRB1.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB1.loc_key, G5_IRB2.loc_key) +G5_IRA.graph.add_uniq_edge(G5_IRB1.loc_key, G5_IRB1.loc_key) -G5_IRA.blocks = dict([(irb.label, irb) for irb in [G5_IRB0, G5_IRB1, G5_IRB2]]) +G5_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G5_IRB0, G5_IRB1, G5_IRB2]]) # graph 6 @@ -317,10 +318,10 @@ G6_IRA = IRATest(symbol_pool) G6_IRB0 = gen_irblock(LBL0, [[ExprAff(B, CST1)]]) G6_IRB1 = gen_irblock(LBL1, [[ExprAff(A, B)]]) -G6_IRA.graph.add_uniq_edge(G6_IRB0.label, G6_IRB1.label) -G6_IRA.graph.add_uniq_edge(G6_IRB1.label, G6_IRB1.label) +G6_IRA.graph.add_uniq_edge(G6_IRB0.loc_key, G6_IRB1.loc_key) +G6_IRA.graph.add_uniq_edge(G6_IRB1.loc_key, G6_IRB1.loc_key) -G6_IRA.blocks = dict([(irb.label, irb) for irb in [G6_IRB0, G6_IRB1]]) +G6_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G6_IRB0, G6_IRB1]]) # graph 7 @@ -330,11 +331,11 @@ G7_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]]) G7_IRB1 = gen_irblock(LBL1, [[ExprAff(B, C)], [ExprAff(A, B)]]) G7_IRB2 = gen_irblock(LBL2, [[ExprAff(D, A)]]) -G7_IRA.graph.add_uniq_edge(G7_IRB0.label, G7_IRB1.label) -G7_IRA.graph.add_uniq_edge(G7_IRB1.label, G7_IRB1.label) -G7_IRA.graph.add_uniq_edge(G7_IRB1.label, G7_IRB2.label) +G7_IRA.graph.add_uniq_edge(G7_IRB0.loc_key, G7_IRB1.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB1.loc_key, G7_IRB1.loc_key) +G7_IRA.graph.add_uniq_edge(G7_IRB1.loc_key, G7_IRB2.loc_key) -G7_IRA.blocks = dict([(irb.label, irb) for irb in [G7_IRB0, G7_IRB1, G7_IRB2]]) +G7_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G7_IRB0, G7_IRB1, G7_IRB2]]) # graph 8 @@ -344,11 +345,11 @@ G8_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]]) G8_IRB1 = gen_irblock(LBL1, [[ExprAff(B, C)], [ExprAff(C, D)]]) G8_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]]) -G8_IRA.graph.add_uniq_edge(G8_IRB0.label, G8_IRB1.label) -G8_IRA.graph.add_uniq_edge(G8_IRB1.label, G8_IRB1.label) -G8_IRA.graph.add_uniq_edge(G8_IRB1.label, G8_IRB2.label) +G8_IRA.graph.add_uniq_edge(G8_IRB0.loc_key, G8_IRB1.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB1.loc_key, G8_IRB1.loc_key) +G8_IRA.graph.add_uniq_edge(G8_IRB1.loc_key, G8_IRB2.loc_key) -G8_IRA.blocks = dict([(irb.label, irb) for irb in [G8_IRB0, G8_IRB1, G8_IRB2]]) +G8_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G8_IRB0, G8_IRB1, G8_IRB2]]) # graph 9 is graph 8 @@ -359,10 +360,10 @@ G10_IRA = IRATest(symbol_pool) G10_IRB1 = gen_irblock(LBL1, [[ExprAff(B, B + CST2)]]) G10_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]]) -G10_IRA.graph.add_uniq_edge(G10_IRB1.label, G10_IRB2.label) -G10_IRA.graph.add_uniq_edge(G10_IRB1.label, G10_IRB1.label) +G10_IRA.graph.add_uniq_edge(G10_IRB1.loc_key, G10_IRB2.loc_key) +G10_IRA.graph.add_uniq_edge(G10_IRB1.loc_key, G10_IRB1.loc_key) -G10_IRA.blocks = dict([(irb.label, irb) for irb in [G10_IRB1, G10_IRB2]]) +G10_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G10_IRB1, G10_IRB2]]) # graph 11 @@ -374,10 +375,10 @@ G11_IRB1 = gen_irblock(LBL1, [[ExprAff(A, B), ExprAff(B, A)]]) G11_IRB2 = gen_irblock(LBL2, [[ExprAff(A, A - B)]]) -G11_IRA.graph.add_uniq_edge(G11_IRB0.label, G11_IRB1.label) -G11_IRA.graph.add_uniq_edge(G11_IRB1.label, G11_IRB2.label) +G11_IRA.graph.add_uniq_edge(G11_IRB0.loc_key, G11_IRB1.loc_key) +G11_IRA.graph.add_uniq_edge(G11_IRB1.loc_key, G11_IRB2.loc_key) -G11_IRA.blocks = dict([(irb.label, irb) +G11_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G11_IRB0, G11_IRB1, G11_IRB2]]) # graph 12 @@ -388,11 +389,11 @@ G12_IRB0 = gen_irblock(LBL0, [[ExprAff(B, CST1)]]) G12_IRB1 = gen_irblock(LBL1, [[ExprAff(A, B)], [ExprAff(B, B + CST2)]]) G12_IRB2 = gen_irblock(LBL2, [[ExprAff(B, A)]]) -G12_IRA.graph.add_uniq_edge(G12_IRB0.label, G12_IRB1.label) -G12_IRA.graph.add_uniq_edge(G12_IRB1.label, G12_IRB2.label) -G12_IRA.graph.add_uniq_edge(G12_IRB1.label, G12_IRB1.label) +G12_IRA.graph.add_uniq_edge(G12_IRB0.loc_key, G12_IRB1.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB1.loc_key, G12_IRB2.loc_key) +G12_IRA.graph.add_uniq_edge(G12_IRB1.loc_key, G12_IRB1.loc_key) -G12_IRA.blocks = dict([(irb.label, irb) for irb in [G12_IRB0, G12_IRB1, +G12_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G12_IRB0, G12_IRB1, G12_IRB2]]) @@ -403,25 +404,25 @@ G13_IRA = IRATest(symbol_pool) G13_IRB0 = gen_irblock(LBL0, [[ExprAff(A, CST1)], #[ExprAff(B, A)], [ExprAff(G13_IRA.IRDst, - ExprLoc(LBL1.loc_key, 32))]]) + ExprLoc(LBL1, 32))]]) G13_IRB1 = gen_irblock(LBL1, [[ExprAff(C, A)], #[ExprAff(A, A + CST1)], [ExprAff(G13_IRA.IRDst, - ExprCond(R, ExprLoc(LBL2.loc_key, 32), - ExprLoc(LBL1.loc_key, 32)))]]) + ExprCond(R, ExprLoc(LBL2, 32), + ExprLoc(LBL1, 32)))]]) G13_IRB2 = gen_irblock(LBL2, [[ExprAff(B, A + CST3)], [ExprAff(A, B + CST3)], [ExprAff(G13_IRA.IRDst, - ExprLoc(LBL1.loc_key, 32))]]) + ExprLoc(LBL1, 32))]]) G13_IRB3 = gen_irblock(LBL3, [[ExprAff(R, C)]]) -G13_IRA.graph.add_uniq_edge(G13_IRB0.label, G13_IRB1.label) -G13_IRA.graph.add_uniq_edge(G13_IRB1.label, G13_IRB2.label) -G13_IRA.graph.add_uniq_edge(G13_IRB2.label, G13_IRB1.label) -G13_IRA.graph.add_uniq_edge(G13_IRB1.label, G13_IRB3.label) +G13_IRA.graph.add_uniq_edge(G13_IRB0.loc_key, G13_IRB1.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB1.loc_key, G13_IRB2.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB2.loc_key, G13_IRB1.loc_key) +G13_IRA.graph.add_uniq_edge(G13_IRB1.loc_key, G13_IRB3.loc_key) -G13_IRA.blocks = dict([(irb.label, irb) for irb in [G13_IRB0, G13_IRB1, +G13_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G13_IRB0, G13_IRB1, G13_IRB2, G13_IRB3]]) # graph 14 @@ -430,28 +431,28 @@ G14_IRA = IRATest(symbol_pool) G14_IRB0 = gen_irblock(LBL0, [[ExprAff(A, CST1)], [ExprAff(G14_IRA.IRDst, - ExprLoc(LBL1.loc_key, 32))] + ExprLoc(LBL1, 32))] ]) G14_IRB1 = gen_irblock(LBL1, [[ExprAff(B, A)], [ExprAff(G14_IRA.IRDst, - ExprCond(C, ExprLoc(LBL2.loc_key, 32), - ExprLoc(LBL3.loc_key, 32)))] + ExprCond(C, ExprLoc(LBL2, 32), + ExprLoc(LBL3, 32)))] ]) G14_IRB2 = gen_irblock(LBL2, [[ExprAff(D, A)], [ExprAff(A, D + CST1)], [ExprAff(G14_IRA.IRDst, - ExprLoc(LBL1.loc_key, 32))] + ExprLoc(LBL1, 32))] ]) G14_IRB3 = gen_irblock(LBL3, [[ExprAff(R, D + B)]]) -G14_IRA.graph.add_uniq_edge(G14_IRB0.label, G14_IRB1.label) -G14_IRA.graph.add_uniq_edge(G14_IRB1.label, G14_IRB2.label) -G14_IRA.graph.add_uniq_edge(G14_IRB2.label, G14_IRB1.label) -G14_IRA.graph.add_uniq_edge(G14_IRB1.label, G14_IRB3.label) +G14_IRA.graph.add_uniq_edge(G14_IRB0.loc_key, G14_IRB1.loc_key) +G14_IRA.graph.add_uniq_edge(G14_IRB1.loc_key, G14_IRB2.loc_key) +G14_IRA.graph.add_uniq_edge(G14_IRB2.loc_key, G14_IRB1.loc_key) +G14_IRA.graph.add_uniq_edge(G14_IRB1.loc_key, G14_IRB3.loc_key) -G14_IRA.blocks = dict([(irb.label, irb) for irb in [G14_IRB0, G14_IRB1, +G14_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G14_IRB0, G14_IRB1, G14_IRB2, G14_IRB3]]) # graph 16 @@ -464,11 +465,11 @@ G15_IRB1 = gen_irblock(LBL1, [[ExprAff(D, A + B)], [ExprAff(B, C)]]) G15_IRB2 = gen_irblock(LBL2, [[ExprAff(R, B)]]) -G15_IRA.graph.add_uniq_edge(G15_IRB0.label, G15_IRB1.label) -G15_IRA.graph.add_uniq_edge(G15_IRB1.label, G15_IRB2.label) -G15_IRA.graph.add_uniq_edge(G15_IRB1.label, G15_IRB1.label) +G15_IRA.graph.add_uniq_edge(G15_IRB0.loc_key, G15_IRB1.loc_key) +G15_IRA.graph.add_uniq_edge(G15_IRB1.loc_key, G15_IRB2.loc_key) +G15_IRA.graph.add_uniq_edge(G15_IRB1.loc_key, G15_IRB1.loc_key) -G15_IRA.blocks = dict([(irb.label, irb) for irb in [G15_IRB0, G15_IRB1, +G15_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G15_IRB0, G15_IRB1, G15_IRB2]]) # graph 16 @@ -482,16 +483,16 @@ G16_IRB3 = gen_irblock(LBL3, [[ExprAff(R, D)]]) G16_IRB4 = gen_irblock(LBL4, [[ExprAff(R, A)]]) G16_IRB5 = gen_irblock(LBL5, [[ExprAff(R, A)]]) -G16_IRA.graph.add_uniq_edge(G16_IRB0.label, G16_IRB1.label) -G16_IRA.graph.add_uniq_edge(G16_IRB1.label, G16_IRB2.label) -G16_IRA.graph.add_uniq_edge(G16_IRB2.label, G16_IRB1.label) -G16_IRA.graph.add_uniq_edge(G16_IRB1.label, G16_IRB3.label) -G16_IRA.graph.add_uniq_edge(G16_IRB3.label, G16_IRB1.label) -G16_IRA.graph.add_uniq_edge(G16_IRB1.label, G16_IRB4.label) -G16_IRA.graph.add_uniq_edge(G16_IRB4.label, G16_IRB1.label) -G16_IRA.graph.add_uniq_edge(G16_IRB1.label, G16_IRB5.label) +G16_IRA.graph.add_uniq_edge(G16_IRB0.loc_key, G16_IRB1.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB1.loc_key, G16_IRB2.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB2.loc_key, G16_IRB1.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB1.loc_key, G16_IRB3.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB3.loc_key, G16_IRB1.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB1.loc_key, G16_IRB4.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB4.loc_key, G16_IRB1.loc_key) +G16_IRA.graph.add_uniq_edge(G16_IRB1.loc_key, G16_IRB5.loc_key) -G16_IRA.blocks = dict([(irb.label, irb) for irb in [G16_IRB0, G16_IRB1, +G16_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G16_IRB0, G16_IRB1, G16_IRB2, G16_IRB3, G16_IRB4, G16_IRB5]]) @@ -505,94 +506,94 @@ G17_IRB1 = gen_irblock(LBL1, [[ExprAff(A, D), ExprAff(B, D)]]) G17_IRB2 = gen_irblock(LBL2, [[ExprAff(A, A - B)]]) -G17_IRA.graph.add_uniq_edge(G17_IRB0.label, G17_IRB1.label) -G17_IRA.graph.add_uniq_edge(G17_IRB1.label, G17_IRB2.label) +G17_IRA.graph.add_uniq_edge(G17_IRB0.loc_key, G17_IRB1.loc_key) +G17_IRA.graph.add_uniq_edge(G17_IRB1.loc_key, G17_IRB2.loc_key) -G17_IRA.blocks = dict([(irb.label, irb) for irb in [G17_IRB0, G17_IRB1, +G17_IRA.blocks = dict([(irb.loc_key, irb) for irb in [G17_IRB0, G17_IRB1, G17_IRB2]]) # Test graph 1 G1_TEST1_DN1 = DependencyNode( - G1_IRB2.label, A, len(G1_IRB2)) + G1_IRB2.loc_key, A, len(G1_IRB2)) -G1_INPUT = (set([G1_TEST1_DN1]), set([G1_IRB0.label])) +G1_INPUT = (set([G1_TEST1_DN1]), set([G1_IRB0.loc_key])) # Test graph 2 G2_TEST1_DN1 = DependencyNode( - G2_IRB2.label, A, len(G2_IRB2)) + G2_IRB2.loc_key, A, len(G2_IRB2)) -G2_INPUT = (set([G2_TEST1_DN1]), set([G2_IRB0.label])) +G2_INPUT = (set([G2_TEST1_DN1]), set([G2_IRB0.loc_key])) # Test graph 3 G3_TEST1_0_DN1 = DependencyNode( - G3_IRB3.label, A, len(G3_IRB3)) + G3_IRB3.loc_key, A, len(G3_IRB3)) -G3_INPUT = (set([G3_TEST1_0_DN1]), set([G3_IRB0.label])) +G3_INPUT = (set([G3_TEST1_0_DN1]), set([G3_IRB0.loc_key])) # Test graph 4 G4_TEST1_DN1 = DependencyNode( - G4_IRB2.label, A, len(G2_IRB0)) + G4_IRB2.loc_key, A, len(G2_IRB0)) -G4_INPUT = (set([G4_TEST1_DN1]), set([G4_IRB0.label])) +G4_INPUT = (set([G4_TEST1_DN1]), set([G4_IRB0.loc_key])) # Test graph 5 G5_TEST1_0_DN1 = DependencyNode( - G5_IRB2.label, A, len(G5_IRB2)) + G5_IRB2.loc_key, A, len(G5_IRB2)) -G5_INPUT = (set([G5_TEST1_0_DN1]), set([G5_IRB0.label])) +G5_INPUT = (set([G5_TEST1_0_DN1]), set([G5_IRB0.loc_key])) # Test graph 6 G6_TEST1_0_DN1 = DependencyNode( - G6_IRB1.label, A, len(G6_IRB1)) + G6_IRB1.loc_key, A, len(G6_IRB1)) -G6_INPUT = (set([G6_TEST1_0_DN1]), set([G6_IRB0.label])) +G6_INPUT = (set([G6_TEST1_0_DN1]), set([G6_IRB0.loc_key])) # Test graph 7 G7_TEST1_0_DN1 = DependencyNode( - G7_IRB2.label, D, len(G7_IRB2)) + G7_IRB2.loc_key, D, len(G7_IRB2)) -G7_INPUT = (set([G7_TEST1_0_DN1]), set([G7_IRB0.label])) +G7_INPUT = (set([G7_TEST1_0_DN1]), set([G7_IRB0.loc_key])) # Test graph 8 G8_TEST1_0_DN1 = DependencyNode( - G8_IRB2.label, A, len(G8_IRB2)) + G8_IRB2.loc_key, A, len(G8_IRB2)) -G8_INPUT = (set([G8_TEST1_0_DN1]), set([G3_IRB0.label])) +G8_INPUT = (set([G8_TEST1_0_DN1]), set([G3_IRB0.loc_key])) # Test 9: Multi elements G9_TEST1_0_DN1 = DependencyNode( - G8_IRB2.label, A, len(G8_IRB2)) + G8_IRB2.loc_key, A, len(G8_IRB2)) G9_TEST1_0_DN5 = DependencyNode( - G8_IRB2.label, C, len(G8_IRB2)) + G8_IRB2.loc_key, C, len(G8_IRB2)) -G9_INPUT = (set([G9_TEST1_0_DN1, G9_TEST1_0_DN5]), set([G8_IRB0.label])) +G9_INPUT = (set([G9_TEST1_0_DN1, G9_TEST1_0_DN5]), set([G8_IRB0.loc_key])) # Test 10: loop at beginning G10_TEST1_0_DN1 = DependencyNode( - G10_IRB2.label, A, len(G10_IRB2)) + G10_IRB2.loc_key, A, len(G10_IRB2)) -G10_INPUT = (set([G10_TEST1_0_DN1]), set([G10_IRB1.label])) +G10_INPUT = (set([G10_TEST1_0_DN1]), set([G10_IRB1.loc_key])) # Test 11: no dual bloc emulation G11_TEST1_DN1 = DependencyNode( - G11_IRB2.label, A, len(G11_IRB2)) + G11_IRB2.loc_key, A, len(G11_IRB2)) -G11_INPUT = (set([G11_TEST1_DN1]), set([G11_IRB0.label])) +G11_INPUT = (set([G11_TEST1_DN1]), set([G11_IRB0.loc_key])) # Test graph 12 -G12_TEST1_0_DN1 = DependencyNode(G12_IRB2.label, B, 1) +G12_TEST1_0_DN1 = DependencyNode(G12_IRB2.loc_key, B, 1) G12_INPUT = (set([G12_TEST1_0_DN1]), set([])) @@ -600,7 +601,7 @@ G12_INPUT = (set([G12_TEST1_0_DN1]), set([])) # All filters -G13_TEST1_0_DN4 = DependencyNode(G13_IRB3.label, R, 1) +G13_TEST1_0_DN4 = DependencyNode(G13_IRB3.loc_key, R, 1) G13_INPUT = (set([G13_TEST1_0_DN4]), set([])) @@ -608,24 +609,24 @@ G13_INPUT = (set([G13_TEST1_0_DN4]), set([])) # All filters -G14_TEST1_0_DN1 = DependencyNode(G14_IRB3.label, R, 1) +G14_TEST1_0_DN1 = DependencyNode(G14_IRB3.loc_key, R, 1) G14_INPUT = (set([G14_TEST1_0_DN1]), set([])) # Test graph 15 -G15_TEST1_0_DN1 = DependencyNode(G15_IRB2.label, R, 1) +G15_TEST1_0_DN1 = DependencyNode(G15_IRB2.loc_key, R, 1) G15_INPUT = (set([G15_TEST1_0_DN1]), set([])) # Test graph 16 -G16_TEST1_0_DN1 = DependencyNode(G16_IRB5.label, R, 1) +G16_TEST1_0_DN1 = DependencyNode(G16_IRB5.loc_key, R, 1) G16_INPUT = (set([G16_TEST1_0_DN1]), set([])) # Test graph 17 -G17_TEST1_DN1 = DependencyNode(G17_IRB2.label, A, 1) +G17_TEST1_DN1 = DependencyNode(G17_IRB2.loc_key, A, 1) G17_INPUT = (set([G17_TEST1_DN1]), set([])) @@ -641,8 +642,8 @@ def flatNode(node): element = int(node.element.arg) else: RuntimeError("Unsupported type '%s'" % type(enode.element)) - label = symbol_pool.loc_key_to_label(node.label) - return (label.name, + name = symbol_pool.loc_key_to_name(node.loc_key) + return (name, element, node.line_nb) else: @@ -740,8 +741,8 @@ def match_results(resultsA, resultsB, nodes): def get_flat_init_depnodes(depnodes): out = [] for node in depnodes: - label = symbol_pool.loc_key_to_label(node.label) - out.append((label.name, + name = symbol_pool.loc_key_to_name(node.loc_key) + out.append((name, node.element.name, node.line_nb, 0)) diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py index a7a9e4be..6693a6f0 100755 --- a/test/arch/msp430/sem.py +++ b/test/arch/msp430/sem.py @@ -26,8 +26,8 @@ def compute(asm, inputstate={}, debug=False): code = mn.asm(instr)[0] instr = mn.dis(code, mode) instr.offset = inputstate.get(PC, 0) - lbl = interm.add_instr(instr) - symexec.run_at(lbl, step=True) + loc_key = interm.add_instr(instr) + symexec.run_at(loc_key) if debug: for k, v in symexec.symbols.items(): if regs_init.get(k, None) != v: diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py index 78cbc243..baa05341 100755 --- a/test/arch/x86/sem.py +++ b/test/arch/x86/sem.py @@ -48,12 +48,12 @@ def compute(ir, mode, asm, inputstate={}, debug=False): def compute_txt(ir, mode, txt, inputstate={}, debug=False): - blocks, symbol_pool = parse_asm.parse_txt(mn, mode, txt) + asmcfg, symbol_pool = parse_asm.parse_txt(mn, mode, txt) symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0) - patches = asmblock.asm_resolve_final(mn, blocks, symbol_pool) + patches = asmblock.asm_resolve_final(mn, asmcfg, symbol_pool) interm = ir(symbol_pool) lbl = symbol_pool.getby_name("main") - for bbl in blocks: + for bbl in asmcfg.blocks: interm.add_block(bbl) return symb_exec(lbl, interm, inputstate, debug) diff --git a/test/arch/x86/unit/mn_cdq.py b/test/arch/x86/unit/mn_cdq.py index b6abc781..15b73913 100644 --- a/test/arch/x86/unit/mn_cdq.py +++ b/test/arch/x86/unit/mn_cdq.py @@ -10,7 +10,7 @@ class Test_CBW_16(Asm_Test_16): MYSTRING = "test CBW 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -31,7 +31,7 @@ class Test_CBW_16_signed(Asm_Test_16): MYSTRING = "test CBW 16 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654381 @@ -52,7 +52,7 @@ class Test_CBW_32(Asm_Test_32): MYSTRING = "test CBW 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -73,7 +73,7 @@ class Test_CBW_32_signed(Asm_Test_32): MYSTRING = "test CBW 32 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654381 @@ -94,7 +94,7 @@ class Test_CDQ_32(Asm_Test_32): MYSTRING = "test cdq 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x77654321 @@ -115,7 +115,7 @@ class Test_CDQ_32_signed(Asm_Test_32): MYSTRING = "test cdq 32 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -136,7 +136,7 @@ class Test_CDQ_64(Asm_Test_64): MYSTRING = "test cdq 64" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567877654321 @@ -157,7 +157,7 @@ class Test_CDQ_64_signed(Asm_Test_64): MYSTRING = "test cdq 64 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567887654321 @@ -178,7 +178,7 @@ class Test_CDQE_64(Asm_Test_64): MYSTRING = "test cdq 64" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567877654321 @@ -199,7 +199,7 @@ class Test_CDQE_64_signed(Asm_Test_64): MYSTRING = "test cdq 64 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567887654321 @@ -220,7 +220,7 @@ class Test_CWD_32(Asm_Test_32): MYSTRING = "test cdq 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -241,7 +241,7 @@ class Test_CWD_32_signed(Asm_Test_32): MYSTRING = "test cdq 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87658321 @@ -262,7 +262,7 @@ class Test_CWD_32(Asm_Test_32): MYSTRING = "test cdq 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -283,7 +283,7 @@ class Test_CWDE_32(Asm_Test_32): MYSTRING = "test cwde 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.EAX = 0x87654321 @@ -304,7 +304,7 @@ class Test_CWDE_32_signed(Asm_Test_32): MYSTRING = "test cwde 32 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x87658321 @@ -325,7 +325,7 @@ class Test_CWDE_64(Asm_Test_64): MYSTRING = "test cwde 64" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567887654321 @@ -346,7 +346,7 @@ class Test_CWDE_64_signed(Asm_Test_64): MYSTRING = "test cwde 64 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567887658321 @@ -367,7 +367,7 @@ class Test_CQO_64(Asm_Test_64): MYSTRING = "test cwde 64" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x1234567887654321 @@ -388,7 +388,7 @@ class Test_CQO_64_signed(Asm_Test_64): MYSTRING = "test cwde 64 signed" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.myjit.cpu.RAX = 0x8234567887658321 diff --git a/test/arch/x86/unit/mn_pushpop.py b/test/arch/x86/unit/mn_pushpop.py index 7ac400c0..bed70ea3 100755 --- a/test/arch/x86/unit/mn_pushpop.py +++ b/test/arch/x86/unit/mn_pushpop.py @@ -21,7 +21,7 @@ class Test_PUSHAD_32(Asm_Test_32): MYSTRING = "test pushad 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -48,7 +48,7 @@ class Test_PUSHA_32(Asm_Test_32): MYSTRING = "test pusha 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -75,7 +75,7 @@ class Test_PUSHA_16(Asm_Test_16): MYSTRING = "test pusha 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -102,7 +102,7 @@ class Test_PUSHAD_16(Asm_Test_16): MYSTRING = "test pushad 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -129,7 +129,7 @@ class Test_PUSH_mode32_32(Asm_Test_32): MYSTRING = "test push mode32 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -152,7 +152,7 @@ class Test_PUSH_mode32_16(Asm_Test_32): MYSTRING = "test push mode32 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -175,7 +175,7 @@ class Test_PUSH_mode16_16(Asm_Test_16): MYSTRING = "test push mode16 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -198,7 +198,7 @@ class Test_PUSH_mode16_32(Asm_Test_16): MYSTRING = "test push mode16 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): init_regs(self) @@ -221,7 +221,7 @@ class Test_POP_mode32_32(Asm_Test_32): MYSTRING = "test pop mode32 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.value = 0x11223344 @@ -243,7 +243,7 @@ class Test_POP_mode32_16(Asm_Test_32): MYSTRING = "test pop mode32 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.value = 0x1122 @@ -265,7 +265,7 @@ class Test_POP_mode16_16(Asm_Test_16): MYSTRING = "test pop mode16 16" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.value = 0x1122 @@ -287,7 +287,7 @@ class Test_POP_mode16_32(Asm_Test_16): MYSTRING = "test pop mode16 32" def prepare(self): - self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + self.myjit.ir_arch.symbol_pool.add_location("lbl_ret", self.ret_addr) def test_init(self): self.value = 0x11223344 diff --git a/test/arch/x86/unit/mn_strings.py b/test/arch/x86/unit/mn_strings.py index 3cb70e2a..44da0a70 100755 --- a/test/arch/x86/unit/mn_strings.py +++ b/test/arch/x86/unit/mn_strings.py @@ -21,7 +21,8 @@ class Test_SCAS(Asm_Test_32): def check(self): assert(self.myjit.cpu.ECX == len(self.MYSTRING)) - assert(self.myjit.cpu.EDI == self.myjit.ir_arch.symbol_pool.getby_name('mystr').offset + len(self.MYSTRING)+1) + mystr = self.myjit.ir_arch.symbol_pool.getby_name('mystr') + assert(self.myjit.cpu.EDI == self.myjit.ir_arch.symbol_pool.loc_key_to_offset(mystr) + len(self.MYSTRING)+1) class Test_MOVS(Asm_Test_32): @@ -42,8 +43,10 @@ class Test_MOVS(Asm_Test_32): def check(self): assert(self.myjit.cpu.ECX == 0) - assert(self.myjit.cpu.EDI == self.myjit.ir_arch.symbol_pool.getby_name('buffer').offset + len(self.MYSTRING)) - assert(self.myjit.cpu.ESI == self.myjit.ir_arch.symbol_pool.getby_name('mystr').offset + len(self.MYSTRING)) + buffer = self.myjit.ir_arch.symbol_pool.getby_name('buffer') + assert(self.myjit.cpu.EDI == self.myjit.ir_arch.symbol_pool.loc_key_to_offset(buffer) + len(self.MYSTRING)) + mystr = self.myjit.ir_arch.symbol_pool.getby_name('mystr') + assert(self.myjit.cpu.ESI == self.myjit.ir_arch.symbol_pool.loc_key_to_offset(mystr) + len(self.MYSTRING)) if __name__ == "__main__": diff --git a/test/core/asmblock.py b/test/core/asmblock.py index 5d240c56..c4a97518 100644 --- a/test/core/asmblock.py +++ b/test/core/asmblock.py @@ -3,7 +3,7 @@ from pdb import pm from miasm2.arch.x86.disasm import dis_x86_32 from miasm2.analysis.binary import Container from miasm2.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \ - AsmLabel, AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \ + AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \ bbl_simplifier from miasm2.core.graph import DiGraphSimplifier, MatchGraphJoker from miasm2.expression.expression import ExprId @@ -19,57 +19,57 @@ first_block = mdis.dis_block(0) assert len(first_block.lines) == 5 print first_block -## Test redisassemble blocks +## Test redisassemble asmcfg first_block_bis = mdis.dis_block(0) assert len(first_block.lines) == len(first_block_bis.lines) print first_block_bis ## Disassembly of several block, with cache -blocks = mdis.dis_multiblock(0) -assert len(blocks) == 17 +asmcfg = mdis.dis_multiblock(0) +assert len(asmcfg) == 17 -## Test redisassemble blocks -blocks = mdis.dis_multiblock(0) -assert len(blocks) == 17 +## Test redisassemble asmcfg +asmcfg = mdis.dis_multiblock(0) +assert len(asmcfg) == 17 ## Equality between assembly lines is not yet implemented -assert len(blocks.heads()) == 1 -assert len(blocks.heads()[0].lines) == len(first_block.lines) +assert len(asmcfg.heads()) == 1 +assert len(asmcfg.loc_key_to_block(asmcfg.heads()[0]).lines) == len(first_block.lines) # Test AsmCFG -assert isinstance(blocks, AsmCFG) -assert len(blocks.pendings) == 0 -assert len(blocks.nodes()) == 17 -assert len(blocks.edges2constraint) == len(blocks.edges()) -assert len(blocks.edges()) == 24 -assert blocks.getby_offset(0x63).lines[0].offset == 0x5f -assert blocks.getby_offset(0x69).lines[0].offset == 0x69 +assert isinstance(asmcfg, AsmCFG) +assert len(asmcfg.pendings) == 0 +assert len(asmcfg.nodes()) == 17 +assert len(asmcfg.edges2constraint) == len(asmcfg.edges()) +assert len(asmcfg.edges()) == 24 +assert asmcfg.getby_offset(0x63).lines[0].offset == 0x5f +assert asmcfg.getby_offset(0x69).lines[0].offset == 0x69 ## Convert to dot -open("graph.dot", "w").write(blocks.dot()) +open("graph.dot", "w").write(asmcfg.dot()) ## Modify the structure: link the first and the last block -leaves = blocks.leaves() +leaves = asmcfg.leaves() assert len(leaves) == 1 -last_block = leaves.pop() +last_block_loc_key = leaves.pop() ### Remove first_block for the rest of the graph -first_block = blocks.heads()[0] +first_block = asmcfg.loc_key_to_block(asmcfg.heads()[0]) assert len(first_block.bto) == 2 -for succ in blocks.successors(first_block): - blocks.del_edge(first_block, succ) +for succ in asmcfg.successors(first_block.loc_key): + asmcfg.del_edge(first_block.loc_key, succ) ### Modification must be reported from the graph assert len(first_block.bto) == 0 -assert last_block in blocks +assert last_block_loc_key in asmcfg.nodes() ### Remove predecessors of last block -for pred in blocks.predecessors(last_block): - blocks.del_edge(pred, last_block) +for pred in asmcfg.predecessors(last_block_loc_key): + asmcfg.del_edge(pred, last_block_loc_key) ### Link first and last block -blocks.add_edge(first_block, last_block, AsmConstraint.c_next) -### Only one link between two blocks +asmcfg.add_edge(first_block.loc_key, last_block_loc_key, AsmConstraint.c_next) +### Only one link between two asmcfg try: - blocks.add_edge(first_block, last_block, AsmConstraint.c_to) + asmcfg.add_edge(first_block, last_block_loc_key, AsmConstraint.c_to) good = False except AssertionError: good = True @@ -79,107 +79,108 @@ assert good assert len(first_block.bto) == 1 assert list(first_block.bto)[0].c_t == AsmConstraint.c_next -## Simplify the obtained graph to keep only blocks which reach a block +## Simplify the obtained graph to keep only asmcfg which reach a block ## finishing with RET def remove_useless_blocks(d_g, graph): """Remove leaves without a RET""" - for block in graph.leaves(): + for leaf_label in graph.leaves(): + block = graph.loc_key_to_block(leaf_label) if block.lines[-1].name != "RET": - graph.del_node(block) + graph.del_block(graph.loc_key_to_block(leaf_label)) ### Use a graph simplifier to recursively apply the simplification pass dg = DiGraphSimplifier() dg.enable_passes([remove_useless_blocks]) -blocks = dg(blocks) +asmcfg = dg(asmcfg) -### Only two blocks should remain -assert len(blocks) == 2 -assert first_block in blocks -assert last_block in blocks +### Only two asmcfg should remain +assert len(asmcfg) == 2 +assert first_block.loc_key in asmcfg.nodes() +assert last_block_loc_key in asmcfg.nodes() ## Graph the final output -open("graph2.dot", "w").write(blocks.dot()) +open("graph2.dot", "w").write(asmcfg.dot()) # Test helper methods -## Label2block should always be updated -assert blocks.label2block(first_block.label) == first_block +## loc_key_to_block should always be updated +assert asmcfg.loc_key_to_block(first_block.loc_key) == first_block testlabel = mdis.symbol_pool.getby_name_create("testlabel") my_block = AsmBlock(testlabel) -blocks.add_node(my_block) -assert len(blocks) == 3 -assert blocks.label2block(first_block.label) == first_block -assert blocks.label2block(my_block.label) == my_block +asmcfg.add_block(my_block) +assert len(asmcfg) == 3 +assert asmcfg.loc_key_to_block(first_block.loc_key) == first_block +assert asmcfg.loc_key_to_block(my_block.loc_key) == my_block -## Bad blocks -assert len(list(blocks.get_bad_blocks())) == 0 -assert len(list(blocks.get_bad_blocks_predecessors())) == 0 +## Bad asmcfg +assert len(list(asmcfg.get_bad_blocks())) == 0 +assert len(list(asmcfg.get_bad_blocks_predecessors())) == 0 ### Add a bad block, not linked testlabel_bad = mdis.symbol_pool.getby_name_create("testlabel_bad") my_bad_block = AsmBlockBad(testlabel_bad) -blocks.add_node(my_bad_block) -assert list(blocks.get_bad_blocks()) == [my_bad_block] -assert len(list(blocks.get_bad_blocks_predecessors())) == 0 +asmcfg.add_block(my_bad_block) +assert list(asmcfg.get_bad_blocks()) == [my_bad_block] +assert len(list(asmcfg.get_bad_blocks_predecessors())) == 0 ### Link the bad block and update edges -### Indeed, a sub-element has been modified (bto from a block from blocks) -my_block.bto.add(AsmConstraintTo(my_bad_block.label)) -blocks.rebuild_edges() -assert list(blocks.get_bad_blocks_predecessors()) == [my_block] +### Indeed, a sub-element has been modified (bto from a block from asmcfg) +my_block.bto.add(AsmConstraintTo(my_bad_block.loc_key)) +asmcfg.rebuild_edges() +assert list(asmcfg.get_bad_blocks_predecessors()) == [my_block.loc_key] ### Test strict option -my_block.bto.add(AsmConstraintTo(my_block.label)) -blocks.rebuild_edges() -assert list(blocks.get_bad_blocks_predecessors(strict=False)) == [my_block] -assert len(list(blocks.get_bad_blocks_predecessors(strict=True))) == 0 +my_block.bto.add(AsmConstraintTo(my_block.loc_key)) +asmcfg.rebuild_edges() +assert list(asmcfg.get_bad_blocks_predecessors(strict=False)) == [my_block.loc_key] +assert len(list(asmcfg.get_bad_blocks_predecessors(strict=True))) == 0 ## Sanity check -blocks.sanity_check() +asmcfg.sanity_check() ### Next on itself testlabel_nextitself = mdis.symbol_pool.getby_name_create("testlabel_nextitself") my_block_ni = AsmBlock(testlabel_nextitself) -my_block_ni.bto.add(AsmConstraintNext(my_block_ni.label)) -blocks.add_node(my_block_ni) +my_block_ni.bto.add(AsmConstraintNext(my_block_ni.loc_key)) +asmcfg.add_block(my_block_ni) error_raised = False try: - blocks.sanity_check() + asmcfg.sanity_check() except RuntimeError: error_raised = True assert error_raised ### Back to a normal state -blocks.del_node(my_block_ni) -blocks.sanity_check() +asmcfg.del_block(my_block_ni) +asmcfg.sanity_check() ### Multiple next on the same node testlabel_target = mdis.symbol_pool.getby_name_create("testlabel_target") my_block_target = AsmBlock(testlabel_target) -blocks.add_node(my_block_target) +asmcfg.add_block(my_block_target) testlabel_src1 = mdis.symbol_pool.getby_name_create("testlabel_src1") testlabel_src2 = mdis.symbol_pool.getby_name_create("testlabel_src2") my_block_src1 = AsmBlock(testlabel_src1) my_block_src2 = AsmBlock(testlabel_src2) -my_block_src1.bto.add(AsmConstraintNext(my_block_target.label)) -blocks.add_node(my_block_src1) +my_block_src1.bto.add(AsmConstraintNext(my_block_target.loc_key)) +asmcfg.add_block(my_block_src1) ### OK for now -blocks.sanity_check() +asmcfg.sanity_check() ### Add a second next from src2 to target (already src1 -> target) -my_block_src2.bto.add(AsmConstraintNext(my_block_target.label)) -blocks.add_node(my_block_src2) +my_block_src2.bto.add(AsmConstraintNext(my_block_target.loc_key)) +asmcfg.add_block(my_block_src2) error_raised = False try: - blocks.sanity_check() + asmcfg.sanity_check() except RuntimeError: error_raised = True assert error_raised -blocks.del_node(my_block_src2) -blocks.sanity_check() +asmcfg.del_block(my_block_src2) +asmcfg.sanity_check() ## Guess block size ### Initial state assert not hasattr(first_block, 'size') assert not hasattr(first_block, 'max_size') -blocks.guess_blocks_size(mdis.arch) +asmcfg.guess_blocks_size(mdis.arch) assert first_block.size == 39 -assert blocks.label2block(my_block_src1.label).size == 0 +assert asmcfg.loc_key_to_block(my_block_src1.loc_key).size == 0 assert first_block.max_size == 39 -assert blocks.label2block(my_block_src1.label).max_size == 0 +assert asmcfg.loc_key_to_block(my_block_src1.loc_key).max_size == 0 ## Check pendings ### Create a pending element @@ -187,122 +188,124 @@ testlabel_pend_src = mdis.symbol_pool.getby_name_create("testlabel_pend_src") testlabel_pend_dst = mdis.symbol_pool.getby_name_create("testlabel_pend_dst") my_block_src = AsmBlock(testlabel_pend_src) my_block_dst = AsmBlock(testlabel_pend_dst) -my_block_src.bto.add(AsmConstraintTo(my_block_dst.label)) -blocks.add_node(my_block_src) +my_block_src.bto.add(AsmConstraintTo(my_block_dst.loc_key)) +asmcfg.add_block(my_block_src) ### Check resulting state -assert len(blocks) == 7 -assert len(blocks.pendings) == 1 -assert my_block_dst.label in blocks.pendings -assert len(blocks.pendings[my_block_dst.label]) == 1 -pending = list(blocks.pendings[my_block_dst.label])[0] -assert isinstance(pending, blocks.AsmCFGPending) +assert len(asmcfg) == 7 +assert len(asmcfg.pendings) == 1 +assert my_block_dst.loc_key in asmcfg.pendings +assert len(asmcfg.pendings[my_block_dst.loc_key]) == 1 +pending = list(asmcfg.pendings[my_block_dst.loc_key])[0] +assert isinstance(pending, asmcfg.AsmCFGPending) assert pending.waiter == my_block_src assert pending.constraint == AsmConstraint.c_to ### Sanity check must fail error_raised = False try: - blocks.sanity_check() + asmcfg.sanity_check() except RuntimeError: error_raised = True assert error_raised ### Pending must disappeared when adding expected block -blocks.add_node(my_block_dst) -assert len(blocks) == 8 -assert len(blocks.pendings) == 0 -blocks.sanity_check() +asmcfg.add_block(my_block_dst) +assert len(asmcfg) == 8 +assert len(asmcfg.pendings) == 0 +asmcfg.sanity_check() # Test block_merge data2 = "31c0eb0c31c9750c31d2eb0c31ffebf831dbebf031edebfc31f6ebf031e4c3".decode("hex") cont2 = Container.from_string(data2) mdis = dis_x86_32(cont2.bin_stream) ## Elements to merge -blocks = mdis.dis_multiblock(0) +asmcfg = mdis.dis_multiblock(0) ## Block alone -blocks.add_node(mdis.dis_block(0x1c)) +asmcfg.add_block(mdis.dis_block(0x1c)) ## Bad block -blocks.add_node(mdis.dis_block(len(data2))) +asmcfg.add_block(mdis.dis_block(len(data2))) ## Dump the graph before merging -open("graph3.dot", "w").write(blocks.dot()) +open("graph3.dot", "w").write(asmcfg.dot()) ## Apply merging -blocks = bbl_simplifier(blocks) +asmcfg = bbl_simplifier(asmcfg) ## Dump the graph after merging -open("graph4.dot", "w").write(blocks.dot()) +open("graph4.dot", "w").write(asmcfg.dot()) ## Check the final state -assert len(blocks) == 5 -assert len(list(blocks.get_bad_blocks())) == 1 -### Check "special" blocks -entry_blocks = blocks.heads() -bad_block = (block for block in entry_blocks - if isinstance(block, AsmBlockBad)).next() -entry_blocks.remove(bad_block) -alone_block = (block for block in entry_blocks - if len(blocks.successors(block)) == 0).next() -entry_blocks.remove(alone_block) +assert len(asmcfg) == 5 +assert len(list(asmcfg.get_bad_blocks())) == 1 +### Check "special" asmcfg +entry_asmcfg = asmcfg.heads() +bad_block_lbl = (lbl for lbl in entry_asmcfg + if isinstance(asmcfg.loc_key_to_block(lbl), AsmBlockBad)).next() +entry_asmcfg.remove(bad_block_lbl) +alone_block = (asmcfg.loc_key_to_block(lbl) for lbl in entry_asmcfg + if len(asmcfg.successors(lbl)) == 0).next() +entry_asmcfg.remove(alone_block.loc_key) assert alone_block.lines[-1].name == "RET" assert len(alone_block.lines) == 2 ### Check resulting function -entry_block = entry_blocks.pop() +entry_block = asmcfg.loc_key_to_block(entry_asmcfg.pop()) assert len(entry_block.lines) == 4 assert map(str, entry_block.lines) == ['XOR EAX, EAX', 'XOR EBX, EBX', 'XOR ECX, ECX', 'JNZ label_3'] -assert len(blocks.successors(entry_block)) == 2 +assert len(asmcfg.successors(entry_block.loc_key)) == 2 assert len(entry_block.bto) == 2 -nextb = blocks.label2block((cons.label for cons in entry_block.bto - if cons.c_t == AsmConstraint.c_next).next()) -tob = blocks.label2block((cons.label for cons in entry_block.bto - if cons.c_t == AsmConstraint.c_to).next()) +nextb = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto + if cons.c_t == AsmConstraint.c_next).next()) +tob = asmcfg.loc_key_to_block((cons.loc_key for cons in entry_block.bto + if cons.c_t == AsmConstraint.c_to).next()) assert len(nextb.lines) == 4 assert map(str, nextb.lines) == ['XOR EDX, EDX', 'XOR ESI, ESI', 'XOR EDI, EDI', 'JMP label_4'] -assert blocks.successors(nextb) == [nextb] +assert asmcfg.successors(nextb.loc_key) == [nextb.loc_key] assert len(tob.lines) == 2 assert map(str, tob.lines) == ['XOR EBP, EBP', 'JMP label_3'] -assert blocks.successors(tob) == [tob] +assert asmcfg.successors(tob.loc_key) == [tob.loc_key] # Check split_block ## Without condition for a split, no change -blocks_bef = blocks.copy() -blocks.apply_splitting(mdis.symbol_pool) -assert blocks_bef == blocks +asmcfg_bef = asmcfg.copy() +asmcfg.apply_splitting(mdis.symbol_pool) +assert asmcfg_bef == asmcfg +open("graph5.dot", "w").write(asmcfg.dot()) ## Create conditions for a block split inside_firstbbl = mdis.symbol_pool.getby_offset(4) tob.bto.add(AsmConstraintTo(inside_firstbbl)) -blocks.rebuild_edges() -assert len(blocks.pendings) == 1 -assert inside_firstbbl in blocks.pendings -blocks.apply_splitting(mdis.symbol_pool) +asmcfg.rebuild_edges() +assert len(asmcfg.pendings) == 1 +assert inside_firstbbl in asmcfg.pendings +asmcfg.apply_splitting(mdis.symbol_pool) ## Check result -assert len(blocks) == 6 -assert len(blocks.pendings) == 0 +assert len(asmcfg) == 6 +assert len(asmcfg.pendings) == 0 assert len(entry_block.lines) == 2 assert map(str, entry_block.lines) == ['XOR EAX, EAX', 'XOR EBX, EBX'] -assert len(blocks.successors(entry_block)) == 1 -newb = blocks.successors(entry_block)[0] +assert len(asmcfg.successors(entry_block.loc_key)) == 1 +lbl_newb = asmcfg.successors(entry_block.loc_key)[0] +newb = asmcfg.loc_key_to_block(lbl_newb) assert len(newb.lines) == 2 assert map(str, newb.lines) == ['XOR ECX, ECX', 'JNZ label_3'] -preds = blocks.predecessors(newb) +preds = asmcfg.predecessors(lbl_newb) assert len(preds) == 2 -assert entry_block in preds -assert tob in preds -assert blocks.edges2constraint[(entry_block, newb)] == AsmConstraint.c_next -assert blocks.edges2constraint[(tob, newb)] == AsmConstraint.c_to +assert entry_block.loc_key in preds +assert tob.loc_key in preds +assert asmcfg.edges2constraint[(entry_block.loc_key, lbl_newb)] == AsmConstraint.c_next +assert asmcfg.edges2constraint[(tob.loc_key, lbl_newb)] == AsmConstraint.c_to # Check double block split data = "74097405b8020000007405b803000000b804000000c3".decode('hex') cont = Container.from_string(data) mdis = dis_x86_32(cont.bin_stream) -blocks = mdis.dis_multiblock(0) +asmcfg = mdis.dis_multiblock(0) ## Check resulting disasm -assert len(blocks.nodes()) == 6 -blocks.sanity_check() +assert len(asmcfg.nodes()) == 6 +asmcfg.sanity_check() ## Check graph structure bbl0 = MatchGraphJoker(name="0") bbl2 = MatchGraphJoker(name="2") @@ -315,8 +318,18 @@ matcher = bbl0 >> bbl2 >> bbl4 >> bbl9 >> bblB >> bbl10 matcher += bbl2 >> bbl9 >> bbl10 matcher += bbl0 >> bblB -solutions = list(matcher.match(blocks)) +solutions = list(matcher.match(asmcfg)) assert len(solutions) == 1 solution = solutions.pop() -for jbbl, block in solution.iteritems(): - assert block.label.offset == int(jbbl._name, 16) +for jbbl, label in solution.iteritems(): + offset = mdis.symbol_pool.loc_key_to_offset(label) + assert offset == int(jbbl._name, 16) + +loc_key_dum = mdis.symbol_pool.getby_name_create("dummy_loc") +asmcfg.add_node(loc_key_dum) +error_raised = False +try: + asmcfg.sanity_check() +except RuntimeError: + error_raised = True +assert error_raised diff --git a/test/core/graph.py b/test/core/graph.py index 9f8afcae..b71c3d51 100644 --- a/test/core/graph.py +++ b/test/core/graph.py @@ -257,7 +257,7 @@ assert len([sol for sol in sols if sol[j1] == 1]) == 1 assert len([sol for sol in sols if sol[j1] == 2]) == 1 ## Check filter -j2 = MatchGraphJoker(name="son", restrict_out=False, filt=lambda node: node < 2) +j2 = MatchGraphJoker(name="son", restrict_out=False, filt=lambda graph, node: node < 2) matcher = j1 >> j2 >> j1 sols = list(matcher.match(graph)) assert len(sols) == 1 diff --git a/test/core/parse_asm.py b/test/core/parse_asm.py index 54f3be1d..fab3a815 100755 --- a/test/core/parse_asm.py +++ b/test/core/parse_asm.py @@ -64,18 +64,19 @@ class TestParseAsm(unittest.TestCase): .string "toto" ''' - blocks, symbol_pool = parse_txt(mn_x86, 32, ASM0) + asmcfg, symbol_pool = parse_txt(mn_x86, 32, ASM0) patches = asm_resolve_final(mn_x86, - blocks, + asmcfg, symbol_pool) lbls = [] for i in xrange(6): lbls.append(symbol_pool.getby_name('lbl%d' % i)) # align test - assert(lbls[5].offset % 0x10 == 0) + offset = symbol_pool.loc_key_to_offset(lbls[5]) + assert(offset % 0x10 == 0) lbl2block = {} - for block in blocks: - lbl2block[block.label] = block + for block in asmcfg.blocks: + lbl2block[block.loc_key] = block # dontsplit test assert(lbls[2] == lbl2block[lbls[1]].get_next()) assert(lbls[3] == lbl2block[lbls[2]].get_next()) @@ -94,13 +95,13 @@ class TestParseAsm(unittest.TestCase): RET ''' - blocks, symbol_pool = parse_txt(mn_x86, 32, ASM0) + asmcfg, symbol_pool = parse_txt(mn_x86, 32, ASM0) lbls = [] for i in xrange(2): lbls.append(symbol_pool.getby_name('lbl%d' % i)) lbl2block = {} - for block in blocks: - lbl2block[block.label] = block + for block in asmcfg.blocks: + lbl2block[block.loc_key] = block # split test assert(lbl2block[lbls[1]].get_next() is None) diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py index f3894927..53aa199d 100644 --- a/test/core/sembuilder.py +++ b/test/core/sembuilder.py @@ -2,22 +2,23 @@ import inspect from pdb import pm from miasm2.core.sembuilder import SemBuilder +from miasm2.core.asmblock import AsmSymbolPool import miasm2.expression.expression as m2_expr -from miasm2.core.asmblock import AsmLabel + + # Test classes class IR(object): + def __init__(self, symbol_pool): + self.symbol_pool = symbol_pool IRDst = m2_expr.ExprId("IRDst", 32) def get_next_instr(self, _): - return AsmLabel(m2_expr.LocKey(0), "NEXT") - - def get_next_label(self, _): - return AsmLabel(m2_expr.LocKey(0), "NEXT") + return m2_expr.LocKey(0) - def gen_label(self): - return AsmLabel(m2_expr.LocKey(1), "GEN") + def get_next_loc_key(self, _): + return m2_expr.LocKey(0) class Instr(object): mode = 32 @@ -44,7 +45,8 @@ def test(Arg1, Arg2, Arg3): a = m2_expr.ExprId('A', 32) b = m2_expr.ExprId('B', 32) c = m2_expr.ExprId('C', 32) -ir = IR() +symbol_pool = AsmSymbolPool() +ir = IR(symbol_pool) instr = Instr() res = test(ir, instr, a, b, c) @@ -58,7 +60,7 @@ for statement in res[0]: print "[+] Blocks:" for irb in res[1]: - print irb.label + print irb.loc_key for assignblk in irb: for expr in assignblk: print expr diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py index 643c59e4..29b3c39d 100644 --- a/test/ir/translators/z3_ir.py +++ b/test/ir/translators/z3_ir.py @@ -1,6 +1,6 @@ import z3 -from miasm2.core.asmblock import AsmLabel, AsmSymbolPool +from miasm2.core.asmblock import AsmSymbolPool from miasm2.expression.expression import * from miasm2.ir.translators.z3_ir import Z3Mem, TranslatorZ3 @@ -143,16 +143,16 @@ for miasm_int, res in [(five, -5), (four, -4)]: assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- -label_histoire = symbol_pool.add_label("label_histoire", 0xdeadbeef) -e7 = ExprLoc(label_histoire.loc_key, 32) +label_histoire = symbol_pool.add_location("label_histoire", 0xdeadbeef) +e7 = ExprLoc(label_histoire, 32) ez3 = translator1.from_expr(e7) z3_e7 = z3.BitVecVal(0xdeadbeef, 32) assert equiv(ez3, z3_e7) # Should just not throw anything to pass -lbl_e8 = symbol_pool.add_label("label_jambe") +lbl_e8 = symbol_pool.add_location("label_jambe") -e8 = ExprLoc(lbl_e8.loc_key, 32) +e8 = ExprLoc(lbl_e8, 32) ez3 = translator1.from_expr(e8) assert not equiv(ez3, z3_e7) |