Include disassembly in MicroJIT scraper output
This commit is contained in:
parent
188c54428c
commit
5f9beb9b1b
@ -11,6 +11,8 @@
|
|||||||
# details.
|
# details.
|
||||||
|
|
||||||
module RubyVM::MicroJIT
|
module RubyVM::MicroJIT
|
||||||
|
ScrapeResult = Struct.new(:pre_call_bytes, :post_call_bytes, :disassembly_lines)
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def target_platform
|
def target_platform
|
||||||
# Note, checking RUBY_PLATRFORM doesn't work when cross compiling
|
# Note, checking RUBY_PLATRFORM doesn't work when cross compiling
|
||||||
@ -117,8 +119,9 @@ module RubyVM::MicroJIT
|
|||||||
raise 'generated code for example too long' unless jmp_idx < 10
|
raise 'generated code for example too long' unless jmp_idx < 10
|
||||||
handler_instructions = instructions[(0..jmp_idx)]
|
handler_instructions = instructions[(0..jmp_idx)]
|
||||||
|
|
||||||
|
disassembly_lines = handler_instructions.map {|_, _, line| line}
|
||||||
puts "Disassembly for the example handler:"
|
puts "Disassembly for the example handler:"
|
||||||
puts handler_instructions.map {|_, _, line| line}
|
puts disassembly_lines
|
||||||
|
|
||||||
|
|
||||||
raise 'rip reference in example makes copying unsafe' if handler_instructions.any? { |_, _, full_line| full_line.downcase.include?('rip') }
|
raise 'rip reference in example makes copying unsafe' if handler_instructions.any? { |_, _, full_line| full_line.downcase.include?('rip') }
|
||||||
@ -144,7 +147,11 @@ module RubyVM::MicroJIT
|
|||||||
post_call_bytes += bytes.split
|
post_call_bytes += bytes.split
|
||||||
end
|
end
|
||||||
|
|
||||||
[pre_call_bytes, post_call_bytes]
|
ScrapeResult.new(
|
||||||
|
comma_separated_hex_string(pre_call_bytes),
|
||||||
|
comma_separated_hex_string(post_call_bytes),
|
||||||
|
disassembly_lines
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def darwin_scrape(instruction_id)
|
def darwin_scrape(instruction_id)
|
||||||
@ -169,13 +176,11 @@ module RubyVM::MicroJIT
|
|||||||
disassemble(handler_offset)
|
disassemble(handler_offset)
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_result(success, pre_call, post_call, pre_call_with_ec, post_call_with_ec)
|
def make_result(success, without_pc, with_pc)
|
||||||
[success ? 1 : 0,
|
[success ? 1 : 0,
|
||||||
[
|
[
|
||||||
['ujit_pre_call_bytes', comma_separated_hex_string(pre_call)],
|
['ujit_without_ec', without_pc],
|
||||||
['ujit_post_call_bytes', comma_separated_hex_string(post_call)],
|
['ujit_with_ec', with_pc],
|
||||||
['ujit_pre_call_with_ec_bytes', comma_separated_hex_string(pre_call_with_ec)],
|
|
||||||
['ujit_post_call_with_ec_bytes', comma_separated_hex_string(post_call_with_ec)]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@ -193,12 +198,14 @@ module RubyVM::MicroJIT
|
|||||||
end
|
end
|
||||||
|
|
||||||
def scrape
|
def scrape
|
||||||
pre, post = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example' })
|
without_ec = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example' })
|
||||||
pre_with_ec, post_with_ec = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example_with_ec' })
|
with_ec = scrape_instruction(RubyVM::Instructions.find_index { |insn| insn.name == 'ujit_call_example_with_ec' })
|
||||||
make_result(true, pre, post, pre_with_ec, post_with_ec)
|
make_result(true, without_ec, with_ec)
|
||||||
rescue => e
|
rescue => e
|
||||||
print_warning("scrape failed: #{e.message}")
|
print_warning("scrape failed: #{e.message}")
|
||||||
make_result(false, ['cc'], ['cc'], ['cc'], ['cc'])
|
int3 = '0xcc'
|
||||||
|
failure_result = ScrapeResult.new(int3, int3, ['int3'])
|
||||||
|
make_result(false, failure_result, failure_result)
|
||||||
end
|
end
|
||||||
|
|
||||||
def print_warning(text)
|
def print_warning(text)
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
% success, byte_arrays = RubyVM::MicroJIT.scrape
|
% success, byte_arrays = RubyVM::MicroJIT.scrape
|
||||||
static const uint8_t ujit_scrape_successful = <%= success %>;
|
static const uint8_t ujit_scrape_successful = <%= success %>;
|
||||||
% byte_arrays.each do |(name, bytes)|
|
% byte_arrays.each do |(prefix, scrape_result)|
|
||||||
static const uint8_t <%= name %>[] = { <%= bytes %> };
|
// Disassembly:
|
||||||
|
% scrape_result.disassembly_lines.each do |line|
|
||||||
|
// <%= line %>
|
||||||
|
% end
|
||||||
|
static const uint8_t <%= prefix %>_pre_call_bytes[] = { <%= scrape_result.pre_call_bytes %> };
|
||||||
|
static const uint8_t <%= prefix %>_post_call_bytes[] = { <%= scrape_result.post_call_bytes %> };
|
||||||
% end
|
% end
|
||||||
|
@ -304,8 +304,8 @@ x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx)
|
|||||||
static void
|
static void
|
||||||
ujit_gen_entry(codeblock_t* cb)
|
ujit_gen_entry(codeblock_t* cb)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < sizeof(ujit_pre_call_with_ec_bytes); ++i)
|
for (size_t i = 0; i < sizeof(ujit_with_ec_pre_call_bytes); ++i)
|
||||||
cb_write_byte(cb, ujit_pre_call_with_ec_bytes[i]);
|
cb_write_byte(cb, ujit_with_ec_pre_call_bytes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,8 +327,8 @@ ujit_gen_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc)
|
|||||||
mov(cb, member_opnd(REG_CFP, rb_control_frame_t, pc), RAX);
|
mov(cb, member_opnd(REG_CFP, rb_control_frame_t, pc), RAX);
|
||||||
|
|
||||||
// Write the post call bytes
|
// Write the post call bytes
|
||||||
for (size_t i = 0; i < sizeof(ujit_post_call_with_ec_bytes); ++i)
|
for (size_t i = 0; i < sizeof(ujit_with_ec_post_call_bytes); ++i)
|
||||||
cb_write_byte(cb, ujit_post_call_with_ec_bytes[i]);
|
cb_write_byte(cb, ujit_with_ec_post_call_bytes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user