Permalink
Browse files

rcpu-disas: ignore invalid instructions when disassembling

  • Loading branch information...
1 parent e1c7bc9 commit 0279279ccd9c04083b9f45e42c5e88a1f9c2af54 @rlane committed Apr 12, 2012
Showing with 40 additions and 35 deletions.
  1. +38 −33 bin/rcpu-disas
  2. +2 −2 lib/rcpu.rb
View
@@ -48,50 +48,55 @@ while not queue.empty?
pc = queue.shift
next if seen_pcs.member? pc
seen_pcs << pc
- inst, new_pc = decode pc
- if inst then
- valid_pcs << pc
- case inst.name
- when :SET, :ADD, :SUB
- if inst.a.is_a? Register and inst.a.name == :PC
- if inst.b.is_a? Literal
- target = if inst.name == :SET
- inst.b.value
- elsif inst.name == :ADD
- new_pc + inst.b.value
- elsif inst.name == :SUB
- new_pc - inst.b.value
+ begin
+ inst, new_pc = decode pc
+
+ if inst then
+ valid_pcs << pc
+ case inst.name
+ when :SET, :ADD, :SUB
+ if inst.a.is_a? Register and inst.a.name == :PC
+ if inst.b.is_a? Literal
+ target = if inst.name == :SET
+ inst.b.value
+ elsif inst.name == :ADD
+ new_pc + inst.b.value
+ elsif inst.name == :SUB
+ new_pc - inst.b.value
+ end
+ queue << target
+ branch_targets << target
+ inst.b = Label.new(mklabel(target))
+ elsif inst.b.is_a? Register and inst.b.name == :POP
+ # Function return, covered by JSR case.
+ else
+ $stderr.puts "unsupported branch: #{inst}"
end
+ else
+ queue << new_pc
+ end
+ when :JSR
+ queue << new_pc
+ if inst.a.is_a? Literal
+ target = inst.a.value
queue << target
branch_targets << target
- inst.b = Label.new(mklabel(target))
- elsif inst.b.is_a? Register and inst.b.name == :POP
- # Function return, covered by JSR case.
+ inst.a = Label.new(mklabel(target))
else
$stderr.puts "unsupported branch: #{inst}"
end
- else
+ when :IFE, :IFN, :IFG, :IFB
+ _, skip_pc = decode new_pc
queue << new_pc
- end
- when :JSR
- queue << new_pc
- if inst.a.is_a? Literal
- target = inst.a.value
- queue << target
- branch_targets << target
- inst.a = Label.new(mklabel(target))
+ queue << skip_pc
+ skippable_pcs << new_pc
else
- $stderr.puts "unsupported branch: #{inst}"
+ queue << new_pc
end
- when :IFE, :IFN, :IFG, :IFB
- _, skip_pc = decode new_pc
- queue << new_pc
- queue << skip_pc
- skippable_pcs << new_pc
- else
- queue << new_pc
end
+ rescue RCPU::DecoderError
+ puts "decoder error at #{pc}: #{$!.message}"
end
end
View
@@ -101,7 +101,7 @@ def to_machine(mem = [])
end
def self.from_code(code, a, b)
- raise DecoderError.new("Invalid opcode #{code}") if code < 1 or code > ALL.size
+ raise DecoderError.new("Invalid basic opcode #{code}") if code < 1 or code > ALL.size
new(ALL[code-1], a, b)
end
@@ -210,7 +210,7 @@ def to_machine(mem = [])
end
def self.from_code(code, a)
- raise DecoderError.new("Invalid opcode #{code}") if code < 1 or code > ALL.size
+ raise DecoderError.new("Invalid nonbasic opcode #{code}") if code < 1 or code > ALL.size
new(ALL[code - 1], a)
end

0 comments on commit 0279279

Please sign in to comment.