aboutsummaryrefslogtreecommitdiffstats
path: root/mjit_c.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2022-12-14 00:12:55 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 22:11:20 -0800
commit3fa4d41460f67791d08d9bec2f8add9dd15f0f07 (patch)
tree730bcfa47eebfa2371adea5d5956253fc49f0cee /mjit_c.c
parentfd04e1b4dbbb0dae130f3de79d69ca94ecdf883e (diff)
downloadruby-3fa4d41460f67791d08d9bec2f8add9dd15f0f07.tar.gz
Implement --mjit-dump-disasm
Diffstat (limited to 'mjit_c.c')
-rw-r--r--mjit_c.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/mjit_c.c b/mjit_c.c
index 9ba023e84b..0af2e4b239 100644
--- a/mjit_c.c
+++ b/mjit_c.c
@@ -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