class Fisk::UnresolvedJumpInstruction
Public Class Methods
new(insn, form, operand)
click to toggle source
# File lib/fisk.rb, line 361 def initialize insn, form, operand @insn = insn @form = form @operand = operand @must_retry = false end
Public Instance Methods
encode(buffer, labels)
click to toggle source
# File lib/fisk.rb, line 380 def encode buffer, labels # Estimate by using a rel32 offset form = find_form "rel32" encoding = form.encodings.first operand_klass = Rel32 if labels.key? target unless @must_retry estimated_offset = labels[target] - (buffer.pos + 6) # 6 seems like a good length if estimated_offset >= -128 && estimated_offset <= 127 # fits in a rel8 operand_klass = Rel8 form = find_form "rel8" encoding = form.encodings.first end end # We don't know what the size of the jump will be, so just write # it out with some dummy data and keep track of the buffer position. # Calculate the real jump offset, then rewind and patch the jump with # the right location. 😩 pos = buffer.pos encoding.encode buffer, [operand_klass.new(0xFE)] jump_len = -(buffer.pos - labels[target]) buffer.seek pos, IO::SEEK_SET encoding.encode buffer, [operand_klass.new(jump_len)] else @must_retry = true encoding.encode buffer, [operand_klass.new(0x0CAFE)] end end
jump?()
click to toggle source
# File lib/fisk.rb, line 368 def jump? true end
retry?()
click to toggle source
# File lib/fisk.rb, line 376 def retry? true end
target()
click to toggle source
# File lib/fisk.rb, line 372 def target @operand.name end
Private Instance Methods
find_form(form_type)
click to toggle source
# File lib/fisk.rb, line 415 def find_form form_type @insn.forms.find { |form| form.operands.first.type == form_type } end