public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/libunwind] f43: Disable C++ exception handling symbols ppc64le, s390x fixes
@ 2026-09-15 10:02 Florian Weimer
  0 siblings, 0 replies; only message in thread
From: Florian Weimer @ 2026-09-15 10:02 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/libunwind
Branch : f43
Commit : 88543f4453a9d1ed248b73933255bec6071ee924
Author : Florian Weimer <fweimer@redhat.com>
Date   : 2026-08-21T17:29:11+02:00
Stats  : +210/-2 in 5 file(s)
URL    : https://src.fedoraproject.org/rpms/libunwind/c/88543f4453a9d1ed248b73933255bec6071ee924?branch=f43

Log:
Disable C++ exception handling symbols ppc64le, s390x fixes

---
diff --git a/libunwind-s390x-backtrace-1.patch b/libunwind-s390x-backtrace-1.patch
new file mode 100644
index 0000000..378cb67
--- /dev/null
+++ b/libunwind-s390x-backtrace-1.patch
@@ -0,0 +1,49 @@
+commit 1e749954a3c941592f46583113a06844be47311a
+Author: Matt Turner <mattst88@gmail.com>
+Date:   Fri Apr 10 11:46:37 2026 -0400
+
+    s390x: detect infinite loop in unw_step()
+    
+    When unwinding through a signal handler on s390x, the unwinder could
+    enter an infinite loop. This happened because dwarf_step() found DWARF
+    unwind info (via the .eh_frame FDE) that produced the same IP with a
+    bogus CFA, causing unw_step() to keep returning > 0 indefinitely.
+    
+    The reason is that setup_fde() initializes all register rules to
+    DWARF_WHERE_SAME instead of DWARF_WHERE_UNDEF (which the DWARF spec
+    requires). When a CIE doesn't explicitly mark the return address
+    register as undefined, the "same value" default causes the unwinder to
+    read a stale return address and loop.
+    
+    Add a defensive check (similar to ARM's arm_exidx_step and x86_64's
+    _unw_step_fallback): if dwarf_step() succeeds but IP is unchanged and
+    CFA didn't increase, stop unwinding.
+    
+    This fixes the s390x cross-compile CI job timing out on Gtest-bt.
+
+diff --git a/src/s390x/Gstep.c b/src/s390x/Gstep.c
+index c6b644177cd40dd9..792f5b6014049834 100644
+--- a/src/s390x/Gstep.c
++++ b/src/s390x/Gstep.c
+@@ -94,6 +94,8 @@ unw_step (unw_cursor_t *cursor)
+ {
+   struct cursor *c = (struct cursor *) cursor;
+   int ret = 0, val = c->validate, sig;
++  unw_word_t old_ip = c->dwarf.ip;
++  unw_word_t old_cfa = c->dwarf.cfa;
+ 
+ #if CONSERVATIVE_CHECKS
+   c->validate = 1;
+@@ -145,5 +147,12 @@ unw_step (unw_cursor_t *cursor)
+   if (unlikely (ret > 0 && c->dwarf.ip == 0))
+     return 0;
+ 
++  if (unlikely (ret > 0 && c->dwarf.ip == old_ip && c->dwarf.cfa <= old_cfa))
++    {
++      Dprintf ("%s: ip unchanged and cfa not advancing; stopping\n",
++               __FUNCTION__);
++      return 0;
++    }
++
+   return ret;
+ }

diff --git a/libunwind-s390x-backtrace-2.patch b/libunwind-s390x-backtrace-2.patch
new file mode 100644
index 0000000..ea503d5
--- /dev/null
+++ b/libunwind-s390x-backtrace-2.patch
@@ -0,0 +1,78 @@
+commit 7ebd4d910c109e171db13d160c6f03e350f57a83
+Author: Matt Turner <mattst88@gmail.com>
+Date:   Fri Apr 10 11:52:25 2026 -0400
+
+    s390x: check for signal frame before dwarf_step()
+    
+    Check for signal frames before attempting DWARF-based unwinding, as ARM
+    and AArch64 already do. The vDSO provides DWARF unwind info for the
+    signal trampoline (__kernel_sigreturn), but this info doesn't correctly
+    describe how to unwind through the signal frame — apply_reg_state()
+    detects ip and cfa unchanged and returns -UNW_EBADFRAME. By checking
+    first, we ensure the s390x signal frame handler (which correctly parses
+    the sigcontext structure) is always used.
+    
+    This fixes Gtest-resume-sig, Ltest-resume-sig, and Ltest-concurrent
+    failures when running the s390x testsuite under QEMU.
+
+diff --git a/src/s390x/Gstep.c b/src/s390x/Gstep.c
+index 792f5b6014049834..aee9c5aee959a01a 100644
+--- a/src/s390x/Gstep.c
++++ b/src/s390x/Gstep.c
+@@ -104,6 +104,18 @@ unw_step (unw_cursor_t *cursor)
+   Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n",
+          c, c->dwarf.ip, c->dwarf.cfa);
+ 
++  /* Check if this is a signal frame before trying DWARF-based unwinding. The
++   * vDSO may provide DWARF info for the signal trampoline that doesn't
++   * correctly describe how to unwind through the signal frame. Checking first
++   * ensures we always use our signal frame handler which correctly parses the
++   * sigcontext.  */
++  sig = unw_is_signal_frame (cursor);
++  if (sig > 0)
++    {
++      c->sigcontext_format = sig;
++      return s390x_handle_signal_frame (cursor);
++    }
++
+   /* Try DWARF-based unwinding... */
+   c->sigcontext_format = S390X_SCF_NONE;
+   ret = dwarf_step (&c->dwarf);
+@@ -114,34 +126,14 @@ unw_step (unw_cursor_t *cursor)
+ 
+   if (unlikely (ret == -UNW_ENOINFO))
+     {
+-      /* GCC doesn't currently emit debug information for signal
+-         trampolines on s390x so we check for them explicitly.
+-
+-         If there isn't debug information available we could also
++      /* If there isn't debug information available we could also
+          try using the backchain (if available).
+ 
+          Other platforms also detect PLT entries here. That's
+          tricky to do reliably on s390x so I've left it out for
+          now.  */
+-
+-      /* Memory accesses here are quite likely to be unsafe. */
+-      c->validate = 1;
+-
+-      /* Check if this is a signal frame. */
+-      sig = unw_is_signal_frame (cursor);
+-      if (sig > 0)
+-        {
+-          c->sigcontext_format = sig;
+-          ret = s390x_handle_signal_frame (cursor);
+-        }
+-      else
+-        {
+-          c->dwarf.ip = 0;
+-          ret = 0;
+-        }
+-
+-      c->validate = val;
+-      return ret;
++      c->dwarf.ip = 0;
++      return 0;
+     }
+ 
+   if (unlikely (ret > 0 && c->dwarf.ip == 0))

diff --git a/libunwind-s390x-backtrace-3.patch b/libunwind-s390x-backtrace-3.patch
new file mode 100644
index 0000000..67cac7f
--- /dev/null
+++ b/libunwind-s390x-backtrace-3.patch
@@ -0,0 +1,48 @@
+commit eb396ff249fd868eb589a385528401d435960bd5
+Author: Matt Turner <mattst88@gmail.com>
+Date:   Sun Apr 19 13:24:10 2026 -0400
+
+    dwarf: don't default SP to CFA on s390x
+    
+    The DWARF standard (§6.4) defines CFA as "the value of the stack
+    pointer at the call site in the previous frame", so defaulting
+    SP=CFA after a step is correct for ABIs where that holds.
+    
+    The s390x ELF ABI [1] defines CFA as R15+160 — the 160-byte
+    mandatory save area / back-chain header that every frame must
+    reserve.  This deviates from the DWARF definition: for a frameless
+    function (no stack allocation), CFA = R15_callee + 160 =
+    R15_caller + 160, not R15_caller.  Defaulting SP=DWARF_WHERE_CFA
+    after stepping through such a function (e.g. the kill syscall
+    wrapper, which emits no DW_CFA_offset rule for R15) therefore
+    produces the wrong R15 for the caller.  The subsequent frame then
+    computes its CFA 160 bytes too high, reads the return address from
+    the wrong location, finds zero, and terminates the unwind after only
+    2 frames instead of the expected ≥3.
+    
+    Exclude s390x from the SP=CFA default (ARM and MIPS N64 are already
+    excluded) so R15 falls back to DWARF_WHERE_SAME and the value from
+    the ucontext is preserved correctly.
+    
+    Fixes Gtest-trace and Ltest-trace on s390x.
+    
+    [1] https://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390/x1564.html
+
+diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
+index f99e8262d10564c5..d4fb63bc0f7e169e 100644
+--- a/src/dwarf/Gparser.c
++++ b/src/dwarf/Gparser.c
+@@ -522,8 +522,11 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr)
+   for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i)
+     set_reg (sr, i, DWARF_WHERE_SAME, 0);
+ 
+-#if !defined(UNW_TARGET_ARM) && !(defined(UNW_TARGET_MIPS) && _MIPS_SIM == _ABI64)
+-  // SP defaults to CFA (but is overridable)
++#if !defined(UNW_TARGET_ARM) && !(defined(UNW_TARGET_MIPS) && _MIPS_SIM == _ABI64) \
++    && !defined(UNW_TARGET_S390X)
++  /* SP defaults to CFA. s390x excluded: CFA = R15+160, so this default gives
++     caller's R15 = CFA instead of R15, breaking frameless functions like kill
++     that never emit DW_CFA_offset for R15. */
+   set_reg (sr, TDEP_DWARF_SP, DWARF_WHERE_CFA, 0);
+ #endif
+ 

diff --git a/libunwind-s390x-glibc-mmap.patch b/libunwind-s390x-glibc-mmap.patch
new file mode 100644
index 0000000..06f58d2
--- /dev/null
+++ b/libunwind-s390x-glibc-mmap.patch
@@ -0,0 +1,23 @@
+commit 7cc4c20fbcf65a9c855fb9d950fad8d0e29b092e
+Author: Sankalp <125449768+sankalpjha555@users.noreply.github.com>
+Date:   Wed Aug 21 12:00:41 2024 +0530
+
+    Fixed Gtest-sig-context and Ltest-sig-context
+    
+    The mi_mmap() function bypassed the standard libc mmap() call and directly invoked syscall(). This caused a "bad address" error on s390x due to differences in how parameters are passed and handled to syscalls on s390x. To avoid this issue, it's recommended to fall back to using the libc mmap() implementation for s390x.
+    
+    Signed-off-by: sankalpjha555 <sankalp@ibm.com>
+
+diff --git a/include/libunwind_i.h b/include/libunwind_i.h
+index 1dbcb6a86d0f1bc6..66186611a63378a4 100644
+--- a/include/libunwind_i.h
++++ b/include/libunwind_i.h
+@@ -226,7 +226,7 @@ do {                                            \
+ static ALWAYS_INLINE void *
+ mi_mmap (void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+ {
+-#if defined(SYS_mmap) && !defined(__i386__)
++#if defined(SYS_mmap) && !defined(__i386__) && !defined(__s390x__)
+   /* Where supported, bypass libc and invoke the syscall directly. */
+ # if defined(__FreeBSD__) // prefer over syscall on *BSD
+   long int ret = __syscall (SYS_mmap, addr, len, prot, flags, fd, offset);

diff --git a/libunwind.spec b/libunwind.spec
index 8c13cbc..8ca2a86 100644
--- a/libunwind.spec
+++ b/libunwind.spec
@@ -46,7 +46,7 @@
 Summary: An unwinding library
 Name: libunwind
 Version: 1.8.3
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: MIT
 URL: http://savannah.nongnu.org/projects/libunwind
 Source: https://github.com/libunwind/libunwind/releases/download/v%{version}/%{name}-%{version}.tar.gz
@@ -58,6 +58,10 @@ Patch2: libunwind-1.3.1-multilib-fix.patch
 Patch5: libunwind-no-dl-iterate-phdr.patch
 # Fix C23 issue
 Patch6: https://github.com/libunwind/libunwind/commit/457612f470f8c0e718cdf7f14ef1ecb583f3b3a6.patch
+Patch7: libunwind-s390x-glibc-mmap.patch
+Patch8: libunwind-s390x-backtrace-1.patch
+Patch9: libunwind-s390x-backtrace-2.patch
+Patch10: libunwind-s390x-backtrace-3.patch
 
 ExclusiveArch: %{arm} aarch64 hppa ia64 mips ppc %{power64} s390x %{ix86} x86_64 riscv64
 
@@ -101,7 +105,7 @@ libtoolize --force
 autoheader
 automake --add-missing
 autoconf
-%configure --enable-static --enable-shared --enable-setjmp=no
+%configure --enable-static --enable-shared --enable-setjmp=no --disable-cxx-exceptions
 make %{?_smp_mflags}
 
 %install
@@ -150,6 +154,12 @@ echo ====================TESTING END=====================
 %{_libexecdir}/libunwind
 
 %changelog
+* Fri Aug 21 2026 Florian Weimer  <fweimer@redhat.com> - 1.8.3-4
+- Disable C++ exception support on all architectures (#2517606)
+- Add libunwind-s390x-glibc-mmap.patch to use glibc mmap on s390x
+  (libunwind mmap did not use the right syscall ABI).
+- Add libunwind-s390x-backtrace-*.patch to fix endless loops in tests.
+
 * Thu Jul 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.3-3
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-15 10:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15 10:02 [rpms/libunwind] f43: Disable C++ exception handling symbols ppc64le, s390x fixes Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox