uClibc linking against libgcc_eh.a, the right thing to do?

Thomas Petazzoni thomas.petazzoni at free-electrons.com
Tue Sep 30 14:17:35 UTC 2014


Hello,

In commit 8d31a6e50db423b89082b64a3250eec1b94a7456 ("buildsys: link
libgcc_eh if DODEBUG"), Bernhard modified the uClibc build system to
link uClibc against libgcc_eh.a if DODEBUG is enabled.

The reason given by the commit log is that in -O0, certain functions
end up calling _Unwind_Resume(), which is implemented in libgcc_eh.a.

However, I believe linking against libgcc_eh.a is wrong, because this
library can only be built by a shared library capable compiler.
However, the first stage gcc that is used to build uClibc is not
necessarily shared library capable.

Until recently, Buildroot was using a three stage gcc build:
gcc-initial, then install uclibc headers and build uclibc start files,
then gcc-intermediate, then build the full uclibc, then build
gcc-final. In this model, things were working fine. However, when
switching to the simpler gcc-initial, then uclibc, then gcc-final build
process, the special case of DODEBUG=y no longer works, because at the
time uclibc is built, libgcc_eh.a doesn't exist yet:

=========
  LD ld-uClibc-0.9.34-git.so
arc-buildroot-linux-uclibc-gcc: error: libgcc_eh.a: No such file or
directory
make[2]: *** [lib/ld-uClibc.so] Error 1
make[1]: *** [.../build/uclibc-arc-mainline-dev/.stamp_built] Error 2
make: *** [_all] Error 2
=========

I believe linking against libgcc_eh.a is the wrong thing to do because
glibc clearly states in its Makeconfig file:

# How to link against libgcc.  Some libgcc functions, such as those
# for "long long" arithmetic or software floating point, can always be
# built without use of C library headers and do not have any global
# state so can safely be linked statically into any executable or
# shared library requiring them; these functions are in libgcc.a.
# Other functions, relating to exception handling, may require C
# library headers to build and it may not be safe to have more than
# one copy of them in a process; these functions are only in
# libgcc_s.so and libgcc_eh.a.
#
# To avoid circular dependencies when bootstrapping, it is desirable
# to avoid use of libgcc_s and libgcc_eh in building glibc.  Where any
# glibc functionality (in particular, thread cancellation) requires
# exception handling, this is implemented through dlopen of libgcc_s
# to avoid unnecessary dependencies on libgcc_s by programs not using
# that functionality; executables built with glibc do not use
# exception handling other than through thread cancellation.
#
# Undefined references to functions from libgcc_eh or libgcc_s may
# arise for code built with -fexceptions.  In the case of statically
# linked programs installed by glibc, unwinding will never actually
# occur at runtime and the use of elf/static-stubs.c to resolve these
# references is safe.  In the case of statically linked test programs
# and test programs built with -fexceptions, unwinding may occur in
# some cases and it is preferable to link with libgcc_eh or libgcc_s
# so that the testing is as similar as possible to how programs will
# be built with the installed glibc.

And then glibc provides its own _Unwind_Resume() implementation so that
it doesn't need to rely on gcc's libgcc_eh.a.

This bug was reported to us (Buildroot people) by Alexey Brodkin
<Alexey.Brodkin at synopsys.com>, who works on the ARC support.

Any input on this issue? What could be the solution to this problem?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


More information about the uClibc mailing list