https://gcc.gnu.org/g:bb9cb9c7c0abb3bad257322f55b60293b7fecf27

commit r16-6561-gbb9cb9c7c0abb3bad257322f55b60293b7fecf27
Author: Xinhui Yang <[email protected]>
Date:   Wed Jan 7 08:59:01 2026 -0700

    [PATCH] ia64: properly include libunwind support during configuration
    
    By using the test `with_system_libunwind', libgcc can use either
    in-house implementation or reference external libunwind symbols.
    However, this breaks the static libgcc.a library, as in t-linux it
    references unwind-compat.c, which turns some _Unwind_* symbols into
    references of the corresponding symbols in libunwind, but libunwind does
    not exist in some conditions (e.g. bootstrapping a toolchain). The
    linker complains about `missing version node for symbol', since it can
    not find the symbol it is referring to.
    
    The unwind-compat.c module should only exist, if system libunwind is
    being used. Also GCC itself should add -lunwind only if this condition
    is met, too.
    
    Implementing better control for whether to embed unwind implementation
    into libgcc to fix this issue.
    
    gcc/
            * config.gcc: limit -lunwind usage by testing if the system
            libunwind is being used.
    
    libgcc/
            * config.host (ia64): include unwind-compat only if the system
            libunwind is being used.
    
            * config/ia64/t-linux-libunwind: include libgcc symver definition
            for libgcc symbols, since it bears the same role as t-linux
            (except libunwind); Include fde-glibc.c since the unwind
            implementation requires _Unwind_FindTableEntry in this file.
    
            * config/ia64/unwind-ia64.c: protect _Unwind_FindTableEntry inside
            inihbit_libc ifndefs to allow it to build with newlib or
            without proper headers.

Diff:
---
 gcc/config.gcc                       | 5 ++++-
 libgcc/config.host                   | 4 +++-
 libgcc/config/ia64/t-linux-libunwind | 4 ++++
 libgcc/config/ia64/unwind-ia64.c     | 9 ++++++++-
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b2a48c02d3be..3cce8876dbc5 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2361,7 +2361,10 @@ ia64*-*-freebsd*)
        ;;
 ia64*-*-linux*)
        tm_file="${tm_file} elfos.h gnu-user.h linux.h glibc-stdint.h 
ia64/sysv4.h ia64/linux.h"
-       tmake_file="${tmake_file} ia64/t-ia64 ia64/t-linux t-libunwind"
+       tmake_file="${tmake_file} ia64/t-ia64 ia64/t-linux"
+       if test x$with_system_libunwind = xyes ; then
+               tmake_file="${tmake_file} t-libunwind"
+       fi
        target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
        ;;
 ia64*-*-hpux*)
diff --git a/libgcc/config.host b/libgcc/config.host
index 2434844b8337..443b4567a7c6 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -957,9 +957,11 @@ ia64*-*-freebsd*)
 ia64*-*-linux*)
        # Don't use crtbeginT.o from *-*-linux* default.
        extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
-       tmake_file="$tmake_file ia64/t-ia64 ia64/t-ia64-elf t-crtfm t-softfp-tf 
ia64/t-softfp t-softfp ia64/t-softfp-compat ia64/t-eh-ia64 t-libunwind 
ia64/t-linux"
+       tmake_file="${tmake_file} ia64/t-ia64 ia64/t-ia64-elf t-crtfm 
t-softfp-tf ia64/t-softfp t-softfp ia64/t-softfp-compat ia64/t-eh-ia64"
        if test x$with_system_libunwind != xyes ; then
                tmake_file="${tmake_file} t-libunwind-elf 
ia64/t-linux-libunwind"
+       else
+               tmake_file="${tmake_file} ia64/t-linux t-libunwind"
        fi
        md_unwind_header=ia64/linux-unwind.h
        ;;
diff --git a/libgcc/config/ia64/t-linux-libunwind 
b/libgcc/config/ia64/t-linux-libunwind
index 8b1736a2d678..daef9e97bdb9 100644
--- a/libgcc/config/ia64/t-linux-libunwind
+++ b/libgcc/config/ia64/t-linux-libunwind
@@ -1,3 +1,7 @@
 # Build libunwind for IA-64 GLIBC based system.
 LIBUNWIND = $(srcdir)/config/ia64/fde-glibc.c \
   $(srcdir)/config/ia64/unwind-ia64.c
+
+LIB2ADDEH += $(srcdir)/config/ia64/fde-glibc.c
+
+SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver
diff --git a/libgcc/config/ia64/unwind-ia64.c b/libgcc/config/ia64/unwind-ia64.c
index d46cf99473c1..a45ea8549554 100644
--- a/libgcc/config/ia64/unwind-ia64.c
+++ b/libgcc/config/ia64/unwind-ia64.c
@@ -1730,6 +1730,7 @@ _Unwind_GetRegionStart (struct _Unwind_Context *context)
 void *
 _Unwind_FindEnclosingFunction (void *pc)
 {
+#ifndef inhibit_libc
   struct unw_table_entry *entp, ent;
   unw_word segment_base, gp;
 
@@ -1738,6 +1739,9 @@ _Unwind_FindEnclosingFunction (void *pc)
     return NULL;
   else
     return (void *)(segment_base + entp->start_offset);
+#else
+  return NULL;
+#endif
 }
 
 /* Get the value of the CFA as saved in CONTEXT.  In GCC/Dwarf2 parlance,
@@ -1780,9 +1784,12 @@ uw_frame_state_for (struct _Unwind_Context *context, 
_Unwind_FrameState *fs)
   for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
     r->when = UNW_WHEN_NEVER;
   context->lsda = 0;
-
+#ifndef inhibit_libc
   entp = _Unwind_FindTableEntry ((void *) context->rp,
                                &segment_base, &context->gp, &ent);
+#else
+  entp = NULL;
+#endif
   if (entp == NULL)
     {
       /* Couldn't find unwind info for this function.  Try an

Reply via email to