[cfe-dev] Choosing the unwinder / C++ low-level libraries in Clang

David Chisnall David.Chisnall at cl.cam.ac.uk
Thu Jul 23 09:04:15 PDT 2015


On 23 Jul 2015, at 16:26, Renato Golin <renato.golin at linaro.org> wrote:
> 
> LLVM's mode { libc++ / libc++abi / libunwind / compiler-rt } is
> equivalent to GCC's { libstdc++ / libgcc* }. The only conflict that
> could arise is when using libc++abi with libstdc++, but that depends
> on how the functions are named. If memory serves me right, I had no
> issue whatsoever when every time I used it.

In the GNU world, libsupc++ is an implementation detail of libstdc++ for the most part.  With libc++, it depends a lot on how it’s packaged - it will link to libsupc++, libc++abi, or libcxxrt either dynamically or statically.  On FreeBSD, we ship libcxxrt.so.1 as a shared library (and libsupc++.so on FreeBSD 9) to make them plugable, and make libc++.so a linker script that links both libc++.so.1 and libcxxrt.so.1.  On other platforms, libc++.{so,dylib} is often a symlink to libc++.so.1 that statically links libsupc++ or libc++abi (or, in some cases, dynamically links libstdc++.so to get its embedded libsupc++).

Libc++abi, libsupc++ and libcxxrt all provide the same symbols, so you should not mix them in a single program, though it is safe to use libc++ and libstdc++ in different libraries (that don’t expose C++ standard library types across the library boundary) in the same program.

On some GNUish platforms, the unwinder is in libgcc_s.so or libgcc_eh.a (for static linking).  Mixing generic unwind implementations is not supported by the Itanium ABI, so you need to pick one, typically the one that the platform defines.  This also needs to be used for C code for __attribute__((cleanup)) to work (and for setjmp/longjmp to work on some platforms, though possibly only Itanium).

I’m not sure what your distinction of Unwind vs EH ABI means.  The Itanium ABI spec has two parts:

- The generic unwinder
- The language-specific EH personality functions (and throw / catch functions).

The generic unwinder is provided by libunwind (either the LLVM one or some derivative of the HP one), or by libgcc_s.so / libgcc_eh.a (depending on whether your statically or dynamically linking).  This library normally also provides the C personality function (libgcc_s and compiler-rt both do), which does very little other than run cleanups.

The C++-specific functionality is in the C++ runtime library (libsupc++, libc++abi, or libcxxrt).  For dynamic linking, this is normally provided indirectly, via libc++ or libstdc++ (either by statically linking it into the standard library or providing a linker script).  For static linking of programs that don’t need the C++ standard library, it’s usually linked explicitly (e.g. $(CC) $(OBJECTS) -lsupc++, instead of $(CXX) $(OBJECTS)).

The core issue seems to be that libcompiler-rt.so does not provide the generic unwinder, which libgcc_s.so does.  This is why in FreeBSD our libgcc_s.so is currently a mix of compiler-rt and libgcc_* code, and we are currently looking at bringing in the LLVM libUnwind.

>> The Compiler-RT repository does include an unwinder, so perhaps this should be built as libcompilerrt_eh.so for platforms that want to use -rtlib=compilerrt?
> 
> No, the unwinder is long gone to its own repository, because of a
> cross-dependency with libc++abi.

I thought the unwinder only used C++ features that didn’t depend on the C++ runtime library (no exceptions, no RTTI) and only depended on some header-only things from elsewhere?

David





More information about the cfe-dev mailing list