diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2022-12-14 00:12:55 -0800 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-05 22:11:20 -0800 |
commit | 3fa4d41460f67791d08d9bec2f8add9dd15f0f07 (patch) | |
tree | 730bcfa47eebfa2371adea5d5956253fc49f0cee /mjit_c.c | |
parent | fd04e1b4dbbb0dae130f3de79d69ca94ecdf883e (diff) | |
download | ruby-3fa4d41460f67791d08d9bec2f8add9dd15f0f07.tar.gz |
Implement --mjit-dump-disasm
Diffstat (limited to 'mjit_c.c')
-rw-r--r-- | mjit_c.c | 43 |
1 files changed, 43 insertions, 0 deletions
@@ -38,6 +38,49 @@ #define SIZEOF(type) RB_SIZE2NUM(sizeof(type)) #define SIGNED_TYPE_P(type) RBOOL((type)(-1) < (type)(1)) +// macOS: brew install capstone +// Ubuntu/Debian: apt-get install libcapstone-dev +// Fedora: dnf -y install capstone-devel +//#ifdef HAVE_LIBCAPSTONE +#if 1 +#include <capstone/capstone.h> + +#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00" + +// Return an array of [address, mnemonic, op_str] +static VALUE +dump_disasm(rb_execution_context_t *ec, VALUE self, VALUE from, VALUE to) +{ + // Prepare for calling cs_disasm + static csh handle; + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) { + rb_raise(rb_eRuntimeError, "failed to make Capstone handle"); + } + size_t from_addr = NUM2SIZET(from); + size_t to_addr = NUM2SIZET(to); + + // Call cs_disasm and convert results to a Ruby array + cs_insn *insns; + size_t count = cs_disasm(handle, (const uint8_t *)from_addr, to_addr - from_addr, from_addr, 0, &insns); + VALUE result = rb_ary_new_capa(count); + 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)); + rb_ary_push(result, vals); + } + + // Free memory used by capstone + cs_free(insns, count); + cs_close(&handle); + return result; +} +#else +static VALUE +mjit_disasm(VALUE self, VALUE from, VALUE to) +{ + return rb_ary_new(); +} +#endif + #include "mjit_c.rbinc" #endif // USE_MJIT |