From a796603d8c40c39478cfff45932834830e0fdfa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 24 Aug 2021 17:29:31 +0200 Subject: [PATCH] Enable LTO. Resolves: rhbz#1990108 --- ...et-rid-of-type-punning-pointer-casts.patch | 186 ++++++++++++++++++ ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch | 58 ++++++ ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch | 29 +++ ruby.spec | 25 ++- 4 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch create mode 100644 ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch create mode 100644 ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch diff --git a/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch b/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch new file mode 100644 index 0000000..b5c80ad --- /dev/null +++ b/ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch @@ -0,0 +1,186 @@ +From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001 +From: Nobuyoshi Nakada +Date: Thu, 5 Aug 2021 20:09:25 +0900 +Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062] + +--- + vm_eval.c | 4 +++- + vm_insnhelper.c | 7 +++++-- + vm_method.c | 41 +++++++++++++++++++++++++--------------- + 3 files changed, 34 insertions(+), 18 deletions(-) + +diff --git a/vm_eval.c b/vm_eval.c +index 6d4b5c3c0b28..7ce9f157e671 100644 +--- a/vm_eval.c ++++ b/vm_eval.c +@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme) + { + struct rb_class_cc_entries *ccs; + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); ++ VALUE ccs_data; + +- if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) { ++ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { + // ok ++ ccs = (struct rb_class_cc_entries *)ccs_data; + } + else { + ccs = vm_ccs_create(klass, cme); +diff --git a/vm_insnhelper.c b/vm_insnhelper.c +index 14928b2afe8e..e186376b24d7 100644 +--- a/vm_insnhelper.c ++++ b/vm_insnhelper.c +@@ -1636,9 +1636,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) + const ID mid = vm_ci_mid(ci); + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); + struct rb_class_cc_entries *ccs = NULL; ++ VALUE ccs_data; + + if (cc_tbl) { +- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { ++ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { ++ ccs = (struct rb_class_cc_entries *)ccs_data; + const int ccs_len = ccs->len; + VM_ASSERT(vm_ccs_verify(ccs, mid, klass)); + +@@ -1705,8 +1707,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) + if (ccs == NULL) { + VM_ASSERT(cc_tbl != NULL); + +- if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) { ++ if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) { + // rb_callable_method_entry() prepares ccs. ++ ccs = (struct rb_class_cc_entries *)ccs_data; + } + else { + // TODO: required? +diff --git a/vm_method.c b/vm_method.c +index 016dba1dbb18..1fd0bd57f7ca 100644 +--- a/vm_method.c ++++ b/vm_method.c +@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid) + { + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); + if (cc_tbl) { +- const struct rb_class_cc_entries *ccs; ++ VALUE ccs; + if (target_mid) { +- if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) { ++ if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) { + fprintf(stderr, " [CCTB] %p\n", (void *)cc_tbl); +- vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL); ++ vm_ccs_dump_i(target_mid, ccs, NULL); + } + } + else { +@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid) + fprintf(stderr, "# vm_mtbl\n"); + while (klass) { + rp_m(" -> ", klass); +- rb_method_entry_t *me; ++ VALUE me; + + if (RCLASS_M_TBL(klass)) { + if (target_mid != 0) { +- if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) { ++ if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) { + rp_m(" [MTBL] ", me); + } + } +@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid) + } + if (RCLASS_CALLABLE_M_TBL(klass)) { + if (target_mid != 0) { +- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) { ++ if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) { + rp_m(" [CM**] ", me); + } + } +@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) + // check only current class + + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); +- struct rb_class_cc_entries *ccs; ++ VALUE ccs_data; + + // invalidate CCs +- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { ++ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { ++ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; + rb_vm_ccs_free(ccs); + rb_id_table_delete(cc_tbl, mid); + RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs); +@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) + } + else { + rb_vm_t *vm = GET_VM(); +- if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { ++ VALUE cme_data = (VALUE) cme; ++ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { + rb_id_table_delete(vm->negative_cme_table, mid); +- vm_me_invalidate_cache((rb_callable_method_entry_t *)cme); ++ vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data); + + RB_DEBUG_COUNTER_INC(cc_invalidate_negative); + } +@@ -1023,6 +1024,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ + { + struct rb_id_table *mtbl; + const rb_callable_method_entry_t *cme; ++ VALUE cme_data; + + if (me) { + if (me->defined_class == 0) { +@@ -1032,7 +1034,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ + + mtbl = RCLASS_CALLABLE_M_TBL(defined_class); + +- if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) { ++ if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) { ++ cme = (rb_callable_method_entry_t *)cme_data; + RB_DEBUG_COUNTER_INC(mc_cme_complement_hit); + VM_ASSERT(callable_method_entry_p(cme)); + VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme)); +@@ -1076,9 +1079,10 @@ cached_callable_method_entry(VALUE klass, ID mid) + ASSERT_vm_locking(); + + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); +- struct rb_class_cc_entries *ccs; ++ VALUE ccs_data; + +- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { ++ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { ++ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; + VM_ASSERT(vm_ccs_p(ccs)); + + if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) { +@@ -1104,12 +1108,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ + + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); + struct rb_class_cc_entries *ccs; ++ VALUE ccs_data; + + if (!cc_tbl) { + cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); + } + +- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { ++ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { ++ ccs = (struct rb_class_cc_entries *)ccs_data; + VM_ASSERT(ccs->cme == cme); + } + else { +@@ -1123,8 +1129,12 @@ negative_cme(ID mid) + { + rb_vm_t *vm = GET_VM(); + const rb_callable_method_entry_t *cme; ++ VALUE cme_data; + +- if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { ++ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { ++ cme = (rb_callable_method_entry_t *)cme_data; ++ } ++ else { + cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL); + rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme); + } diff --git a/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch b/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch new file mode 100644 index 0000000..9d218e5 --- /dev/null +++ b/ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch @@ -0,0 +1,58 @@ +From 72317b333b85eed483ad00bcd4f40944019a7c13 Mon Sep 17 00:00:00 2001 +From: "xtkoba+ruby@gmail.com" +Date: Fri, 13 Aug 2021 13:45:53 +0000 +Subject: [PATCH] Ignore `DW_FORM_ref_addr` [Bug #17052] + +Ignore `DW_FORM_ref_addr` form and other forms that are not supposed +to be used currently. +--- + addr2line.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/addr2line.c b/addr2line.c +index fed1a8da84e5..92c6da5e3bea 100644 +--- a/addr2line.c ++++ b/addr2line.c +@@ -1592,14 +1592,31 @@ di_read_cu(DebugInfoReader *reader) + } + + static void +-read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line) ++read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line) + { + char *p = reader->p; + char *q = reader->q; + int level = reader->level; + DIE die; + +- reader->p = reader->current_cu + abstract_origin; ++ switch (form) { ++ case DW_FORM_ref1: ++ case DW_FORM_ref2: ++ case DW_FORM_ref4: ++ case DW_FORM_ref8: ++ case DW_FORM_ref_udata: ++ reader->p = reader->current_cu + abstract_origin; ++ break; ++ case DW_FORM_ref_addr: ++ goto finish; /* not supported yet */ ++ case DW_FORM_ref_sig8: ++ goto finish; /* not supported yet */ ++ case DW_FORM_ref_sup4: ++ case DW_FORM_ref_sup8: ++ goto finish; /* not supported yet */ ++ default: ++ goto finish; ++ } + if (!di_read_die(reader, &die)) goto finish; + + /* enumerate abbrev */ +@@ -1664,7 +1681,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, + /* 1 or 3 */ + break; /* goto skip_die; */ + case DW_AT_abstract_origin: +- read_abstract_origin(reader, v.as.uint64, &line); ++ read_abstract_origin(reader, v.form, v.as.uint64, &line); + break; /* goto skip_die; */ + } + } diff --git a/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch b/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch new file mode 100644 index 0000000..74636e5 --- /dev/null +++ b/ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch @@ -0,0 +1,29 @@ +From a9977ba2f9863e3fb1b2346589ebbca67d80536c Mon Sep 17 00:00:00 2001 +From: Nobuyoshi Nakada +Date: Sat, 14 Aug 2021 10:08:19 +0900 +Subject: [PATCH] Constified addr2line.c + +--- + addr2line.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/addr2line.c b/addr2line.c +index 8ee4416650d3..fed1a8da84e5 100644 +--- a/addr2line.c ++++ b/addr2line.c +@@ -1137,12 +1137,12 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa + set_uint_value(v, read_uleb128(reader)); + break; + case DW_FORM_ref_addr: +- if (reader->address_size == 4) { ++ if (reader->format == 4) { + set_uint_value(v, read_uint32(&reader->p)); +- } else if (reader->address_size == 8) { ++ } else if (reader->format == 8) { + set_uint_value(v, read_uint64(&reader->p)); + } else { +- fprintf(stderr,"unknown address_size:%d", reader->address_size); ++ fprintf(stderr,"unknown format:%d", reader->format); + abort(); + } + break; diff --git a/ruby.spec b/ruby.spec index 3555964..f872625 100644 --- a/ruby.spec +++ b/ruby.spec @@ -22,7 +22,7 @@ %endif -%global release 155 +%global release 156 %{!?release_string:%define release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}} # The RubyGems library has to stay out of Ruby directory tree, since the @@ -83,10 +83,6 @@ %bcond_without hardening_test %endif -# LTO appears to cause some issue to SEGV handler. -# https://bugs.ruby-lang.org/issues/17052 -%define _lto_cflags %{nil} - Summary: An interpreter of object-oriented scripting language Name: ruby Version: %{ruby_version} @@ -153,6 +149,18 @@ Patch9: ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1920533 # https://bugs.ruby-lang.org/issues/17585 Patch15: ruby-dwarf5-avoid_crash-r1.patch +# Fix segfaults with enabled LTO. +# https://bugs.ruby-lang.org/issues/18062 +# https://github.com/ruby/ruby/pull/4716 +Patch16: ruby-3.1.0-Get-rid-of-type-punning-pointer-casts.patch +# DWARF5/LTO fixes for SIGSEV handler. +# https://bugs.ruby-lang.org/issues/17052 +# https://github.com/ruby/ruby/commit/72317b333b85eed483ad00bcd4f40944019a7c13 +Patch17: ruby-3.1.0-Ignore-DW_FORM_ref_addr.patch +# https://bugs.ruby-lang.org/issues/17052#note-9 +# https://bugs.ruby-lang.org/attachments/download/8974/ruby-addr2line-DW_FORM_ref_addr.patch +# https://github.com/ruby/ruby/commit/a9977ba2f9863e3fb1b2346589ebbca67d80536c +Patch18: ruby-3.1.0-addr2line-DW_FORM_ref_addr.patch # Avoid possible timeout errors in TestBugReporter#test_bug_reporter_add. # https://bugs.ruby-lang.org/issues/16492 Patch19: ruby-2.7.1-Timeout-the-test_bug_reporter_add-witout-raising-err.patch @@ -595,6 +603,9 @@ rm -rf ext/fiddle/libffi* %patch6 -p1 %patch9 -p1 %patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 %patch19 -p1 %patch20 -p1 @@ -1411,6 +1422,10 @@ mv test/fiddle/test_import.rb{,.disable} %changelog +* Wed Aug 25 2021 Vít Ondruch - 3.0.2-156 +- Enable LTO. + Resolves: rhbz#1990108 + * Wed Aug 25 2021 Carlos O'Donell - 3.0.1-155 - Rebuilt for libffi 3.4.2 SONAME transition (second attempt). Related: rhbz#1891914