[Soc-coordination] Report 5: Provide an alternative to libstdc++ with libc++

Andrej Belym white.wolf.2105 at gmail.com
Sun Jul 29 18:47:48 UTC 2012


Hello,
it is fifth report for project "Provide alternative to libstdc++ with
libc++", mentored by Sylvestre Ledru.

On last weeks I've made some work.

Firstly, I've updated package version to svn160132. Great major change in
this revision is enabled atomics operations provided by libc++.  Also I
filled package documentation (README.Debian, README.source, copyright),
added script to simplify use g++ with libc++. Next my mentor uploaded
package with these changes to 'experimental' Debian repository.

I modified some files for multiarch[1] compatibility. It means that
different by architecture (i386,x86_64) versions of package can be
installed together. Side effect of these changes is build-dependency of
dh-exec. [2]

More interesting part of my work was to replace lower parts of C++ stack
behind libc++abi. Typical C++ stack consists 3 levels: STL - standard
template library (top), ABI - application binary interface library, and
stack unwinding library for exception support (bottom)[3]. Now we replaced
first two parts of C++ library, and we are trying replace lowest. Please,
see simple sheme below:

unwind lib      =>       ABI lib            =>      Std lib        =>
 end-app
     |                                 |                               |
libgcc_s or            libcxxrt,                     libstdc++,
  libunwind             libc++abi                  libc++,
                              libsupc++                    uClibc++

So we replaced libstdc++ to libc++, and libsupc++ to libc++. libsupc++
doen't present explicit in system, because it's statically linked with
libstdc++.

We are try replacing libgcc_s to libunwind[4], but there are some troubles
on this way.

Current version of clang doesn't support other libunwind libraries. Linking
libgcc is hard-coded in clang source code. Also clang 3.1 doesn't support
flag '-nodefaultlibs' that deprecate linking of all standard libraries[5].
So I've created patch for clang++ that links libunwind instead of libgcc if
-stdlib=libc++ flag is set. If flag -static-libgcc will be specified,
libunwind will be staticaly linked. Also I backported patch that enables
-nodefaultlibs flag, for properly building libc++ and libc++abi. Original
patch accepted in revision 156771, and can be found here: [5].

Current build of libunwind from Debian repository doesn't have some
features to be used with libunwind. So:
a) C++ exception support, that can be achieved by configuring libunwind
with --enable-cxx--exception and then building.
b) Static version of libunwind could be compiled with -fPIC to be used in
shared libraries (like libgcc with key -static-libgcc)
Also when I builded libc++ and libunwind with g++  (only linking objects
compiled by clang++, because clang didn't supported -nodefaultlibs at that
time), I got unresolved dependency '__gcc_personality_v0'. But when I'm
building with 'clang -nodefaultlibs' now, I don't can represent this case.

Patches for clang has been send to my mentor (because he is maintainer of
llvm and clang), patches for libunwind has been send to BTS with wishlist
priority. [6][7]

But that's not all, and I go deeper :). Behind C++ stack C standard library
and compiler runtime lib is placed. As first glibc (default in Debian),
uClibc, dietlibc etc. can be used. Second library provided by compiler.

Currently clang uses libgcc[8] as RT library, but LLVM team created own
implementation - compiler-rt[9]. Below is explanation about roles of
libgcc, libgcc_s,  libgcc_eh and compiler-rt.

libgcc and libgcc_s is GCC runtime libraries, that contains some low-level
functions: arithmetical shifts, multiplication, division, comparisons,
operations with software float numbers, and exception handling (stack
unwinding). [8]

Differences between libgcc and libgcc_s:
a) libgcc is static, libgcc_s is shared (I think _s means shared)
b) libgcc_s contains exception handling functions, libgcc doesn't (there is
static library called libgcc_eh that contains these functions. _eh is
probably "exception handling")

So libgcc (+libgcc_eh) is just static version of libgcc_s.

Runtime library must be linked to any C/C++ application. Small difference
is that C apps uses static version by default, and C++ uses dynamic. In
most cases C apps doesn't needed in exceptions handling support (if they
doesn't uses it explicit), so these functions has been moved from main
libgcc to libgcc_eh. libgcc_s links to C apps with key '-as-needed' - so
only if application really uses exceptions handling.

compiler_rt[9] is compiler runtime library that contains low-level
compiler-support functions without exception handling, so it's replacement
for libgcc, not libgcc_s. Also compiler_rt builds only in static mode. Plus
compiler_rt has additional features - built-in support of address sanitizer
(memory error checking tool) and profiler (gcov).

Because compiler_rt doen't have exception handling functions, we need
third-party implementation of it (i.e. libunwind).

So this part provided by libgcc(static)/libclang_rt isn't explicit part of
C++ stack. C++ "inherits" it from C stack (because C++ is "C with classes"
:))

So new stack compared to default Linux C++ stack:
libgcc (C) -> libgcc_eh (C++) \
         or                                         |-> libsupc++ ->
libstdc++   (default stack)
       libgcc_s  (C & C++)            /


compiler_rt (C) -> libunwind (C++) -> libc++abi -> libc++      (new stack).
_______________________________________________________

Now we have:

libgcc (C) -> libunwind (C++) -> libc++abi -> libc++

Now compiler-rt isn't provided for Debian, and we (I and my mentor) are
working  at this problem.

In conclusion, i would say that most targets of my planning have been
achieved. I've created package that builds from SVN repository and was
uploaded to Debian experimental. Package provides scripts to simplify usage
libc++ with clang++ and g++, and it is installed as alternatives for
/usr/bin/c++ (default c++ compiler) using update-alternatives. So further
I'll test package with Debian GNU/kFreeBSD and Debian GNU/Hurd, try build
it and use it. Also I'll continue replace lowest part of C++ stack.

Thanks.

Links:
[1] http://wiki.debian.org/Multiarch
[2] http://wiki.debian.org/Multiarch/Implementation
[3] http://wiki.osdev.org/C%2B%2B_Exception_Support
[4] http://savannah.nongnu.org/projects/libunwind
[5] http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021424.html
[6] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=682194
[7] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=682196
[8] http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html
[9] http://compiler-rt.llvm.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/soc-coordination/attachments/20120729/7e3a24ea/attachment.html>


More information about the Soc-coordination mailing list