RJIT: Simplify how Capstone is used in tests

This commit is contained in:
Takashi Kokubun 2023-03-13 20:40:24 -07:00
parent 1c8e69d602
commit d8344559b2
4 changed files with 9 additions and 19 deletions

View File

@ -58,8 +58,8 @@ module RubyVM::RJIT
(@mem_block...(@mem_block + @mem_size)).include?(addr) (@mem_block...(@mem_block + @mem_size)).include?(addr)
end end
def dump_disasm(from, to, io: STDOUT, color: true) def dump_disasm(from, to, io: STDOUT, color: true, test: false)
C.dump_disasm(from, to).each do |address, mnemonic, op_str| C.dump_disasm(from, to, test:).each do |address, mnemonic, op_str|
@comments.fetch(address, []).each do |comment| @comments.fetch(address, []).each do |comment|
io.puts colorize(" # #{comment}", bold: true, color:) io.puts colorize(" # #{comment}", bold: true, color:)
end end

View File

@ -420,7 +420,7 @@ static size_t rjit_insn_exits[VM_INSTRUCTION_SIZE] = { 0 };
// Return an array of [address, mnemonic, op_str] // Return an array of [address, mnemonic, op_str]
static VALUE static VALUE
dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to) dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to, VALUE test)
{ {
VALUE result = rb_ary_new(); VALUE result = rb_ary_new();
#ifdef HAVE_LIBCAPSTONE #ifdef HAVE_LIBCAPSTONE
@ -434,7 +434,8 @@ dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to)
// Call cs_disasm and convert results to a Ruby array // Call cs_disasm and convert results to a Ruby array
cs_insn *insns; cs_insn *insns;
size_t count = cs_disasm(handle, (const uint8_t *)from_addr, to_addr - from_addr, from_addr, 0, &insns); size_t base_addr = RTEST(test) ? 0 : from_addr; // On tests, start from 0 for output stability.
size_t count = cs_disasm(handle, (const uint8_t *)from_addr, to_addr - from_addr, base_addr, 0, &insns);
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
VALUE vals = rb_ary_new_from_args(3, LONG2NUM(insns[i].address), rb_str_new2(insns[i].mnemonic), rb_str_new2(insns[i].op_str)); VALUE vals = rb_ary_new_from_args(3, LONG2NUM(insns[i].address), rb_str_new2(insns[i].mnemonic), rb_str_new2(insns[i].op_str));
rb_ary_push(result, vals); rb_ary_push(result, vals);

View File

@ -48,8 +48,8 @@ module RubyVM::RJIT # :nodoc: all
# @param from [Integer] - From address # @param from [Integer] - From address
# @param to [Integer] - To address # @param to [Integer] - To address
def dump_disasm(from, to) def dump_disasm(from, to, test: false)
Primitive.dump_disasm(from, to) Primitive.dump_disasm(from, to, test)
end end
# Convert a Ruby object to a VALUE in Integer # Convert a Ruby object to a VALUE in Integer

View File

@ -166,7 +166,7 @@ module RubyVM::RJIT
asm.jmp([:rax, 8]) # JMP r/m64 (Mod 01: [reg]+disp8) asm.jmp([:rax, 8]) # JMP r/m64 (Mod 01: [reg]+disp8)
asm.jmp(:rax) # JMP r/m64 (Mod 11: reg) asm.jmp(:rax) # JMP r/m64 (Mod 11: reg)
assert_compile(asm, <<~EOS) assert_compile(asm, <<~EOS)
0x0: jmp 0x2 0x0: jmp 2
0x2: jmp 0xff 0x2: jmp 0xff
0x7: jmp qword ptr [rax + 8] 0x7: jmp qword ptr [rax + 8]
0xa: jmp rax 0xa: jmp rax
@ -338,23 +338,12 @@ module RubyVM::RJIT
end_addr = @cb.write_addr end_addr = @cb.write_addr
io = StringIO.new io = StringIO.new
@cb.dump_disasm(start_addr, end_addr, io:, color: false) @cb.dump_disasm(start_addr, end_addr, io:, color: false, test: true)
io.seek(0) io.seek(0)
disasm = io.read disasm = io.read
disasm.gsub!(/^ /, '') disasm.gsub!(/^ /, '')
disasm.sub!(/\n\z/, '') disasm.sub!(/\n\z/, '')
disasm.gsub!(/0x(\h{12})/) do
offset = $1.to_i(16) - start_addr
if offset.negative?
"-0x#{offset.to_s(16)}"
else
"0x#{offset.to_s(16)}"
end
end
(start_addr...end_addr).each do |addr|
disasm.gsub!("0x#{addr.to_s(16)}", "0x#{(addr - start_addr).to_s(16)}")
end
disasm disasm
end end
end end