[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#934315: ruby2.5: FTBFS on sparc64 due to alignment issues



Hello!

On 8/9/19 6:05 PM, John Paul Adrian Glaubitz wrote:
>> Would it be possible to backport the patch for the Debian package to
>> fix this issue for ruby2.5? [2] Attaching the patch as well.
> 
> Patch doesn't apply as-is unfortunately. I'll try to backport it.

While I was able to backport the patch, it still does not fix the crash
for me.

I'm attaching it in any case, but it would be nice if Ruby could be updated
to version 2.6 soonish as that version fixes the bug and has also been out
for a while now (since last year).

The new 2.6 version should also make some of the patches in debian/patches
obsolete.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
Index: ruby2.5-2.5.5/compile.c
===================================================================
--- ruby2.5-2.5.5.orig/compile.c
+++ ruby2.5-2.5.5/compile.c
@@ -8089,6 +8089,25 @@ ibf_dump_pos(struct ibf_dump *dump)
     return (unsigned int)rb_str_strlen(dump->str);
 }
 
+static void
+ibf_dump_align(struct ibf_dump *dump, size_t align)
+{
+    ibf_offset_t pos = ibf_dump_pos(dump);
+    if (pos % align) {
+        static const char padding[sizeof(VALUE)];
+        size_t size = align - ((size_t)pos % align);
+#if SIZEOF_LONG > SIZEOF_INT
+        if (pos + size >= UINT_MAX) {
+            rb_raise(rb_eRuntimeError, "dump size exceeds");
+        }
+#endif
+        for (; size > sizeof(padding); size -= sizeof(padding)) {
+            rb_str_cat(dump->str, padding, sizeof(padding));
+        }
+        rb_str_cat(dump->str, padding, size);
+    }
+}
+
 static ibf_offset_t
 ibf_dump_write(struct ibf_dump *dump, const void *buff, unsigned long size)
 {
@@ -8116,6 +8135,8 @@ ibf_load_alloc(const struct ibf_load *lo
     return buff;
 }
 
+#define IBF_W_ALIGN(type) (RUBY_ALIGNOF(type) > 1 ? ibf_dump_align(dump, RUBY_ALIGNOF(type)) : (void)0)
+
 #define IBF_W(b, type, n) (type *)(VALUE)ibf_dump_write(dump, (b), sizeof(type) * (n))
 #define IBF_WV(variable)   ibf_dump_write(dump, &(variable), sizeof(variable))
 #define IBF_WP(b, type, n) ibf_dump_write(dump, (b), sizeof(type) * (n))
@@ -9021,6 +9042,7 @@ ibf_dump_object_struct(struct ibf_dump *
 	range.beg = (long)ibf_dump_object(dump, beg);
 	range.end = (long)ibf_dump_object(dump, end);
 
+	IBF_W_ALIGN(struct ibf_object_struct_range);
 	IBF_WV(range);
     }
     else {
@@ -9184,6 +9206,8 @@ lbf_dump_object_object(struct ibf_dump *
     ibf_offset_t current_offset = ibf_dump_pos(dump);
     obj_header.type = TYPE(obj);
 
+    IBF_W_ALIGN(ibf_offset_t);
+
     if (SPECIAL_CONST_P(obj)) {
 	if (RB_TYPE_P(obj, T_SYMBOL) ||
 	    RB_TYPE_P(obj, T_FLOAT)) {
Index: ruby2.5-2.5.5/include/ruby/defines.h
===================================================================
--- ruby2.5-2.5.5.orig/include/ruby/defines.h
+++ ruby2.5-2.5.5/include/ruby/defines.h
@@ -376,6 +376,16 @@ void rb_ia64_flushrs(void);
 # endif
 #endif
 
+#ifdef RUBY_ALIGNOF
+/* OK, take that definition */
+#elif defined(__cplusplus) && (__cplusplus >= 201103L)
+#define RUBY_ALIGNOF alignof
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#define RUBY_ALIGNOF _Alignof
+#else
+#define RUBY_ALIGNOF(type) ((size_t)offsetof(struct { char f1; type f2; }, f2))
+#endif
+
 RUBY_SYMBOL_EXPORT_END
 
 #if defined(__cplusplus)

Reply to: