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.
---
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 b0fa43b5eba..6b08827c3e0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2359,7 +2359,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 82ea1772f51..d7025e9077f 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 8b1736a2d67..daef9e97bdb 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 75208eae60a..a746358da5c 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
--
2.51.1