Syncing with trunk
git-svn-id: file:///home/svn/framework3/trunk@5718 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
a87cbe1c5e
commit
6ca97f33f4
|
@ -13,8 +13,10 @@ module Metasm
|
||||||
class DecodedInstruction
|
class DecodedInstruction
|
||||||
# the instance of InstructionBlock this di is into
|
# the instance of InstructionBlock this di is into
|
||||||
attr_accessor :block
|
attr_accessor :block
|
||||||
# our offset (in bytes) from the start of the block
|
# our offset (in bytes) from the start of the block, used only for hexdump
|
||||||
attr_accessor :block_offset
|
attr_accessor :block_offset
|
||||||
|
# the address of the instruction's first byte in memory
|
||||||
|
attr_accessor :address
|
||||||
# the disassembled data
|
# the disassembled data
|
||||||
attr_accessor :instruction, :opcode
|
attr_accessor :instruction, :opcode
|
||||||
# our, length in bytes
|
# our, length in bytes
|
||||||
|
@ -29,14 +31,14 @@ class DecodedInstruction
|
||||||
@bin_length = 0
|
@bin_length = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def address
|
|
||||||
@block.address + @block_offset
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_addr
|
def next_addr
|
||||||
address + @bin_length
|
address + @bin_length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def block_head?
|
||||||
|
self == @block.list.first
|
||||||
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
if block
|
if block
|
||||||
bin = @block.edata.data[@block.edata_ptr+@block_offset, @bin_length].unpack('C*').map { |c| '%02x' % c }.join
|
bin = @block.edata.data[@block.edata_ptr+@block_offset, @bin_length].unpack('C*').map { |c| '%02x' % c }.join
|
||||||
|
@ -151,6 +153,10 @@ class InstructionBlock
|
||||||
@backtracked_for = []
|
@backtracked_for = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bin_length
|
||||||
|
(di = @list.last) ? di.block_offset + di.bin_length : 0
|
||||||
|
end
|
||||||
|
|
||||||
# splits the current block into a new one with all di from address addr to end
|
# splits the current block into a new one with all di from address addr to end
|
||||||
# caller is responsible for rebacktracing new.bt_for to regenerate correct old.btt/new.btt
|
# caller is responsible for rebacktracing new.bt_for to regenerate correct old.btt/new.btt
|
||||||
def split(addr)
|
def split(addr)
|
||||||
|
@ -174,7 +180,8 @@ class InstructionBlock
|
||||||
# adds a decodedinstruction to the block list, updates di.block and di.block_offset
|
# adds a decodedinstruction to the block list, updates di.block and di.block_offset
|
||||||
def add_di(di)
|
def add_di(di)
|
||||||
di.block = self
|
di.block = self
|
||||||
di.block_offset = (@list.empty? ? 0 : (@list.last.block_offset + @list.last.bin_length))
|
di.block_offset = bin_length
|
||||||
|
di.address ||= @address + di.block_offset
|
||||||
@list << di
|
@list << di
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -855,7 +862,7 @@ puts " finalize subfunc #{Expression[subfunc]}" if debug_backtrace
|
||||||
|
|
||||||
if di = @decoded[addr]
|
if di = @decoded[addr]
|
||||||
if di.kind_of? DecodedInstruction
|
if di.kind_of? DecodedInstruction
|
||||||
split_block(di.block, di.address) if di.block_offset != 0 # this updates di.block
|
split_block(di.block, di.address) if not di.block_head? # this updates di.block
|
||||||
di.block.add_from(from, from_subfuncret ? :subfuncret : :normal) if from and from != :default
|
di.block.add_from(from, from_subfuncret ? :subfuncret : :normal) if from and from != :default
|
||||||
bf = di.block
|
bf = di.block
|
||||||
end
|
end
|
||||||
|
@ -1741,7 +1748,7 @@ puts " backtrace_indirection for #{ind.target} failed: #{ev}" if debug_backtra
|
||||||
def dump(dump_data=true, &b)
|
def dump(dump_data=true, &b)
|
||||||
b ||= proc { |l| puts l }
|
b ||= proc { |l| puts l }
|
||||||
@sections.sort.each { |addr, edata|
|
@sections.sort.each { |addr, edata|
|
||||||
blockoffs = @decoded.values.map { |di| Expression[di.block.address, :-, addr].reduce if di.kind_of? DecodedInstruction and di.block_offset == 0 }.grep(::Integer).sort.reject { |o| o < 0 or o >= edata.length }
|
blockoffs = @decoded.values.map { |di| Expression[di.block.address, :-, addr].reduce if di.kind_of? DecodedInstruction and di.block_head? }.grep(::Integer).sort.reject { |o| o < 0 or o >= edata.length }
|
||||||
b[@program.dump_section_header(addr, edata)]
|
b[@program.dump_section_header(addr, edata)]
|
||||||
if not dump_data and edata.length > 16*1024 and blockoffs.empty?
|
if not dump_data and edata.length > 16*1024 and blockoffs.empty?
|
||||||
b["// [#{edata.length} data bytes]"]
|
b["// [#{edata.length} data bytes]"]
|
||||||
|
@ -1750,15 +1757,14 @@ puts " backtrace_indirection for #{ind.target} failed: #{ev}" if debug_backtra
|
||||||
unk_off = 0
|
unk_off = 0
|
||||||
# blocks.sort_by { |b| b.addr }.each { |b|
|
# blocks.sort_by { |b| b.addr }.each { |b|
|
||||||
edata.length.times { |i|
|
edata.length.times { |i|
|
||||||
if di = @decoded[addr+i] and di.kind_of? DecodedInstruction and di.block_offset == 0
|
if di = @decoded[addr+i] and di.kind_of? DecodedInstruction and di.block_head?
|
||||||
if unk_off != di.block.edata_ptr
|
if unk_off != di.block.edata_ptr
|
||||||
b["\n// ------ overlap (#{unk_off-di.block.edata_ptr}) ------"]
|
b["\n// ------ overlap (#{unk_off-di.block.edata_ptr}) ------"]
|
||||||
elsif di.block.from_normal.kind_of? ::Array
|
elsif di.block.from_normal.kind_of? ::Array
|
||||||
b["\n"]
|
b["\n"]
|
||||||
end
|
end
|
||||||
dump_block(di.block, &b)
|
dump_block(di.block, &b)
|
||||||
di = di.block.list.last
|
unk_off = i + di.block.bin_length
|
||||||
unk_off = i + di.block_offset + di.bin_length
|
|
||||||
elsif i >= unk_off
|
elsif i >= unk_off
|
||||||
next_off = blockoffs.find { |bo| bo > i } || edata.length
|
next_off = blockoffs.find { |bo| bo > i } || edata.length
|
||||||
if dump_data or next_off - i < 16
|
if dump_data or next_off - i < 16
|
||||||
|
|
|
@ -401,7 +401,7 @@ class GraphViewWidget < Gtk::HBox
|
||||||
else
|
else
|
||||||
@selected_boxes = []
|
@selected_boxes = []
|
||||||
@caret_box = nil
|
@caret_box = nil
|
||||||
@hl_word = nil
|
#@hl_word = nil
|
||||||
end
|
end
|
||||||
redraw
|
redraw
|
||||||
end
|
end
|
||||||
|
@ -413,6 +413,7 @@ class GraphViewWidget < Gtk::HBox
|
||||||
|
|
||||||
def doubleclick(ev)
|
def doubleclick(ev)
|
||||||
if b = find_box_xy(ev.x, ev.y)
|
if b = find_box_xy(ev.x, ev.y)
|
||||||
|
@mousemove_origin = nil
|
||||||
if @hl_word and @zoom >= 0.90 and @zoom <= 1.1
|
if @hl_word and @zoom >= 0.90 and @zoom <= 1.1
|
||||||
@parent_widget.focus_addr(@hl_word)
|
@parent_widget.focus_addr(@hl_word)
|
||||||
else
|
else
|
||||||
|
@ -978,6 +979,10 @@ class GraphViewWidget < Gtk::HBox
|
||||||
@curcontext = Graph.new 'testic'
|
@curcontext = Graph.new 'testic'
|
||||||
@curcontext.root_addrs = dasm_find_roots(addr)
|
@curcontext.root_addrs = dasm_find_roots(addr)
|
||||||
gui_update
|
gui_update
|
||||||
|
# find an address that can be shown if addr is not
|
||||||
|
if not @curcontext.box.find { |b| b[:line_address].index(addr) }
|
||||||
|
addr = @curcontext.box.first[:line_address].values.first
|
||||||
|
end
|
||||||
return focus_addr(addr, false)
|
return focus_addr(addr, false)
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
|
|
|
@ -630,7 +630,7 @@ class Ia32
|
||||||
# emulate ret <n>
|
# emulate ret <n>
|
||||||
al = cp.typesize[:ptr]
|
al = cp.typesize[:ptr]
|
||||||
if sym.attributes.to_a.include? 'stdcall'
|
if sym.attributes.to_a.include? 'stdcall'
|
||||||
argsz = sym.type.args.inject(al) { |sum, a| sum += (cp.sizeof(a) + al - 1) / al * al }
|
argsz = sym.type.args.to_a.inject(al) { |sum, a| sum += (cp.sizeof(a) + al - 1) / al * al }
|
||||||
df.backtrace_binding[:esp] = Expression[:esp, :+, argsz]
|
df.backtrace_binding[:esp] = Expression[:esp, :+, argsz]
|
||||||
else
|
else
|
||||||
df.backtrace_binding[:esp] = Expression[:esp, :+, al]
|
df.backtrace_binding[:esp] = Expression[:esp, :+, al]
|
||||||
|
|
Loading…
Reference in New Issue