metasm/debug.rb in metasm-1.0.3 vs metasm/debug.rb in metasm-1.0.4

- old
+ new

@@ -14,11 +14,11 @@ :oneshot, # current bp state: :active, :inactive (internal use), :disabled (user-specified) :state, # type: type of breakpoint (:bpx = soft, :hwbp = hard, :bpm = memory) :type, - # Expression if this is a conditionnal bp + # Expression if this is a conditional bp # may be a Proc, String or Expression, evaluated every time the breakpoint hits # if it returns 0 or false, the breakpoint is ignored :condition, # Proc to run if this bp has a callback :action, @@ -458,11 +458,11 @@ # retrieve the di at a given address, disassemble if needed # TODO make it so this doesn't interfere with other 'real' disassembler later commands, eg disassemble() or disassemble_fast_deep() # (right now, when they see the block already present they stop all processing) def init_bpx_disassemble(addr) - @disassembler.disassemble_fast_block(addr) + @disassembler.disassemble_fast(addr) @disassembler.di_at(addr) end # checks if bp has an emul_instr # do the lazy initialization if needed @@ -610,14 +610,14 @@ # to be called right before resuming execution of the target # run_m is the method that should be called if the execution is stopped # due to a side-effect of the debugger (bpx with wrong condition etc) # returns nil if the execution should be avoided (just deleted the dead thread/process) def check_pre_run(run_m, *run_a) - if @dead_process + if @dead_process ||= nil del_pid return - elsif @dead_thread + elsif @dead_thread ||= nil del_tid return elsif @state == :running return end @@ -892,11 +892,11 @@ end end # checks if @breakpoint_cause is valid, or was obsoleted by the user changing pc def check_breakpoint_cause - if bp = @breakpoint_cause and + if bp = breakpoint_cause and (bp.type == :bpx or (bp.type == :hwbp and bp.internal[:type] == :x)) and pc != bp.address bp = @breakpoint_cause = nil end bp @@ -1272,11 +1272,11 @@ } Expression[e].bind(bd).reduce { |i| if i.kind_of? Indirection and p = i.pointer.reduce and p.kind_of? ::Integer i.len ||= @cpu.size/8 p &= (1 << @cpu.size) - 1 if p < 0 - Expression.decode_imm(@memory, i.len, @cpu, p) + @memory.decode_imm(p, i.len, @cpu) end } end alias resolve resolve_expr @@ -1288,15 +1288,15 @@ # accepts a range or begin/end address to read memory, or a register name def [](arg0, arg1=nil) if arg1 arg0 = resolve_expr(arg0) if not arg0.kind_of? ::Integer arg1 = resolve_expr(arg1) if not arg1.kind_of? ::Integer - @memory[arg0, arg1].to_str + (@memory[arg0, arg1] || '').to_str elsif arg0.kind_of? ::Range arg0.begin = resolve_expr(arg0.begin) if not arg0.begin.kind_of? ::Integer # cannot happen, invalid ruby Range arg0.end = resolve_expr(arg0.end) if not arg0.end.kind_of? ::Integer - @memory[arg0].to_str + (@memory[arg0] || '').to_str else get_reg_value(arg0) end end @@ -1438,8 +1438,43 @@ def read_mapped_range(addr, len) # try to use a single get_page call s = @memory.get_page(addr, len) || '' s.length == len ? s : (s = @memory[addr, len] ? s.to_str : nil) + end +end + +class CPU + # return the CPU register used to store the current instruction pointer + def dbg_register_pc + @dbg_register_pc ||= :pc + end + + # return the list of CPU registers + def dbg_register_list + @dbg_register_list ||= [dbg_register_pc] + end + + # return the list of flags for the CPU + def dbg_flag_list + @dbg_flag_list ||= [] + end + + # return a hash with register name => register size in bits + def dbg_register_size + @dbg_register_size ||= Hash.new(@size) + end + + # returns true if stepover is different from stepinto for this instruction + def dbg_need_stepover(dbg, addr, di) + di and di.opcode.props[:saveip] + end + + # activate a software breakpoint + def dbg_enable_bp(dbg, bp) + end + + # deactivate a software breakpoint + def dbg_disable_bp(dbg, bp) end end end