mirror of
https://anongit.gentoo.org/git/repo/gentoo.git
synced 2025-07-21 22:53:31 +02:00
145 lines
4.6 KiB
Diff
145 lines
4.6 KiB
Diff
From c8f02d5d170c5373eeef98d6f6354ae7c726e29b Mon Sep 17 00:00:00 2001
|
|
From: jj <john-git@ofjj.net>
|
|
Date: Mon, 11 Dec 2023 19:22:30 +0100
|
|
Subject: [PATCH] dynldr: ruby3.3 compat
|
|
|
|
---
|
|
metasm/dynldr.rb | 64 ++++++++++++++++++++++++++++--------------------
|
|
1 file changed, 37 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/metasm/dynldr.rb b/metasm/dynldr.rb
|
|
index 74bf786f2..a7b807703 100644
|
|
--- a/metasm/dynldr.rb
|
|
+++ b/metasm/dynldr.rb
|
|
@@ -9,7 +9,7 @@
|
|
|
|
module Metasm
|
|
class DynLdr
|
|
- # basic C defs for ruby internals - 1.8 and 1.9 compat - x86/x64
|
|
+ # basic C defs for ruby internals - 1.8, 1.9, 3.3 compat - x86/x64
|
|
RUBY_H = <<EOS
|
|
#line #{__LINE__}
|
|
typedef uintptr_t VALUE;
|
|
@@ -26,7 +26,7 @@ class DynLdr
|
|
struct rb_string_t {
|
|
VALUE flags;
|
|
VALUE klass;
|
|
- VALUE len;
|
|
+ long len;
|
|
char *ptr;
|
|
union {
|
|
long capa;
|
|
@@ -38,7 +38,7 @@ class DynLdr
|
|
struct rb_array_t {
|
|
VALUE flags;
|
|
VALUE klass;
|
|
- VALUE len;
|
|
+ long len;
|
|
union {
|
|
long capa;
|
|
VALUE shared;
|
|
@@ -52,41 +52,45 @@ class DynLdr
|
|
extern VALUE *rb_eRuntimeError __attribute__((import));
|
|
extern VALUE *rb_eArgError __attribute__((import));
|
|
|
|
-// allows generating a ruby1.9 dynldr.so from ruby1.8
|
|
-#ifndef DYNLDR_RUBY_19
|
|
-#define DYNLDR_RUBY_19 #{RUBY_VERSION >= '1.9' ? 1 : 0}
|
|
-#endif
|
|
-
|
|
#if #{RUBY_VERSION >= '2.0' ? 1 : 0}
|
|
// flonums. WHY?
|
|
// also breaks Qtrue/Qnil
|
|
#define rb_float_new rb_float_new_in_heap
|
|
#endif
|
|
|
|
-#if DYNLDR_RUBY_19
|
|
+#if #{RUBY_VERSION >= '1.9' ? 0 : 1}
|
|
+ #define T_STRING 0x07
|
|
+ #define T_ARRAY 0x09
|
|
+ #define T_FIXNUM 0x0a
|
|
+ #define T_MASK 0x3f
|
|
+ #define STR_PTR(o) (RString(o)->ptr)
|
|
+ #define STR_LEN(o) (RString(o)->len)
|
|
+ #define ARY_PTR(o) (RArray(o)->ptr)
|
|
+ #define ARY_LEN(o) (RArray(o)->len)
|
|
+#else
|
|
#define T_STRING 0x05
|
|
#define T_ARRAY 0x07
|
|
#define T_FIXNUM 0x15
|
|
#define T_MASK 0x1f
|
|
#define RSTRING_NOEMBED (1<<13)
|
|
+#if #{RUBY_VERSION >= '3.2' ? 0 : 1}
|
|
+ // ruby1.9 .. 3.2
|
|
#define STR_PTR(o) ((RString(o)->flags & RSTRING_NOEMBED) ? RString(o)->ptr : (char*)&RString(o)->len)
|
|
#define STR_LEN(o) ((RString(o)->flags & RSTRING_NOEMBED) ? RString(o)->len : (RString(o)->flags >> 14) & 0x1f)
|
|
+#else
|
|
+ // ruby3.2+: len is used for NOEMBED strings, and the str buffer starts right after len (off 8+8+4 on win64)
|
|
+ // TODO find a better way to test, not depending on the compiling interpreter ?
|
|
+ #define STR_PTR(o) ((RString(o)->flags & RSTRING_NOEMBED) ? RString(o)->ptr : (((char*)&RString(o)->len) + sizeof(long)))
|
|
+ #define STR_LEN(o) RString(o)->len
|
|
+#endif
|
|
#define RARRAY_EMBED (1<<13)
|
|
#define ARY_PTR(o) ((RArray(o)->flags & RARRAY_EMBED) ? (VALUE*)&RArray(o)->len : RArray(o)->ptr)
|
|
- #define ARY_LEN(o) ((RArray(o)->flags & RARRAY_EMBED) ? ((RArray(o)->flags >> 15) & 3) : RArray(o)->len)
|
|
-#else
|
|
- #define T_STRING 0x07
|
|
- #define T_ARRAY 0x09
|
|
- #define T_FIXNUM 0x0a
|
|
- #define T_MASK 0x3f
|
|
- #define STR_PTR(o) (RString(o)->ptr)
|
|
- #define STR_LEN(o) (RString(o)->len)
|
|
- #define ARY_PTR(o) (RArray(o)->ptr)
|
|
- #define ARY_LEN(o) (RArray(o)->len)
|
|
+ // RVARGC uses more bits, should be 0/unused in earlier ruby versions
|
|
+ #define ARY_LEN(o) ((RArray(o)->flags & RARRAY_EMBED) ? ((RArray(o)->flags >> 15) & 0xff) : RArray(o)->len)
|
|
#endif
|
|
|
|
-#if #{nil.object_id == 4 ? 1 : 0}
|
|
-// ruby1.8
|
|
+#if #{(RUBY_VERSION < '3.0' and nil.object_id == 4) ? 1 : 0}
|
|
+// ruby1.8 (Qnil changed in 1.9 and back in 3.3
|
|
#define TYPE(x) (((VALUE)(x) & 1) ? T_FIXNUM : (((VALUE)(x) < 0x07) || (((VALUE)(x) & 0xf) == 0xe)) ? 0x40 : RString(x)->flags & T_MASK)
|
|
#else
|
|
// ruby2.0+, USE_FLONUM, world is hell
|
|
@@ -138,7 +142,6 @@ class DynLdr
|
|
#define os_load_sym_ord(l, s) 0U
|
|
#endif
|
|
|
|
-extern int *cb_ret_table;
|
|
extern void *callback_handler;
|
|
extern void *callback_id_0;
|
|
extern void *callback_id_1;
|
|
@@ -207,13 +210,12 @@ class DynLdr
|
|
else
|
|
rb_raise(*rb_eArgError, "Invalid lib");
|
|
|
|
- if (TYPE(func) != T_STRING && TYPE(func) != T_FIXNUM)
|
|
- rb_raise(*rb_eArgError, "Invalid func");
|
|
-
|
|
- if (TYPE(func) == T_FIXNUM)
|
|
+ if (TYPE(func) == T_STRING)
|
|
+ p = os_load_sym(h, STR_PTR(func));
|
|
+ else if (TYPE(func) == T_FIXNUM)
|
|
p = os_load_sym_ord(h, VAL2INT(func));
|
|
else
|
|
- p = os_load_sym(h, STR_PTR(func));
|
|
+ rb_raise(*rb_eArgError, "Invalid func");
|
|
|
|
return INT2VAL(p);
|
|
}
|
|
@@ -354,6 +356,14 @@ class DynLdr
|
|
}
|
|
#endif
|
|
|
|
+unsigned long long ruby_abi_version(void) __attribute__((export))
|
|
+{
|
|
+ // mandatory to be loadable in a dev ruby build
|
|
+ // TODO find expected value in current interpreter ?
|
|
+ return 0;
|
|
+ // disable the value check interpreter side: #{ENV['RUBY_ABI_CHECK'] = '0'}
|
|
+}
|
|
+
|
|
int Init_dynldr(void) __attribute__((export_as(Init_<insertfilenamehere>))) // to patch before parsing to match the .so name
|
|
{
|
|
dynldr = rb_const_get(rb_const_get(*rb_cObject, rb_intern("Metasm")), rb_intern("DynLdr"));
|