[cfe-dev] libc++abi on linux

David Chisnall csdavec at swan.ac.uk
Thu Jul 12 04:38:11 PDT 2012


On 12 Jul 2012, at 10:48, Ben Pope wrote:

> OK, so let's assume I'd like to keep the C++ ABI compatible with the 
> last few years of GCC (I want to use Clang, not base my entire platform 
> on it, for now).  I also want to be able to use libc++. lets ignore STL 
> compatibility for now - I know I'll have to also compile anything that 
> uses STL in its interface if I want my new code to depend on it.  But, 
> for example, I would like to be able to use openssl.so that my platform 
> provides (presumably built by GCC 4.6).  I can't think of anything 
> really common with a C++ interface.

In that case, you want to be changing as little as possible.  You almost certainly want to be using libgcc_s, as pretty much any library you use will link to it and you don't want to be introducing duplicate symbols.  If you might want to link to other C++ libraries, then you want to use your platform's native C++ ABI library for the same reason.  On GNU platforms, this is libsupc++.  On FreeBSD it is libsupc++ or libcxxrt, depending on the version.  On Darwin it is libc++abi.

> Oh.  compiler-rt, more to think about.  Awesomeness!

Hopefully you don't have to think about compiler-rt, only the compiler does..  

> Can somebody explain to me the pieces of this puzzle?  There are a bunch 
> of pieces on llvm.org, do they even belong to the same puzzle?
> libc++
> libc++abi
> compiler-rt
> The missing piece is libunwind?
> 
> What are the GNU toolchain equivalents?  Are there even 1:1 equivalents?

There are some pictures in my FOSDEM talk about the new GPL-free C++ stack in FreeBSD.  It's fairly simple though:

For any C file, your compiler will generate an object file.  If there are some language features that are not implemented in hardware for your target (e.g. soft float functions, atomic operations on large types), then it will emit calls to a support library.  These are provided by compiler-rt.  In the GNU world they are provided by libgcc or libgcc_s (the .so parts, for when you don't want multiple copies of the same code in one program).

The generic (language-agnostic) unwind library is also in libgcc_s in the GNU stack.  In PathScale's stack it's in libeh (libunwind).  In FreeBSD, it will probably end up in a separate libeh too.  Unwinding is split into two parts: language-agnostic and language-specific.  Each stack frame has a personality function associated with it for implementing the language-specific behaviour.  The generic unwinder calls this for each stack frame as it unwinds.  Debugging personality functions is the exact opposite of fun.

compiler-rt provides a personality function for C, which just calls cleanup functions, because C does not provide a mechanism for catching exceptions (standard C doesn't let you run cleanups either, but a few things in the C standard do need you to, and the GNU __attribute__((cleanup)) extension lets you register explicit cleanups.

On top of this, you typically have libc, providing your interface to the operating system.  On GNU platforms, this is glibc.  

The C++ ABI library site on top of this.  For GNUish platforms it implements the ABI described here:

http://sourcery.mentor.com/public/cxx-abi/

Often (e.g. ARM) with some modifications.  For example, ARM function pointers use the low bit to indicate thumb code so BLX / BX instructions can set the instruction decoder to the correct mode.  This provides, more or less, the same things for C++ that libgcc[_s] or compiler-rt provide for C: the functions and data structures that the compiler will insert references to directly just from the use of certain language features.  For example, use of typeid or dynamic_cast become calls out to this library, even if you don't link a STL implementation.  In the GNU world, this is libsupc++.  In FreeBSD, it may be libcxxrt or libsupc++, depending on the version.

On top of all of this, you have the STL implementation, e.g. GNU libstdc++, Apache libstdcxx, or LLVM libc++. This depends on functionality of everything below it and is, aside from being referenced in the standard, just another C++ library.  You can write C++ programs that don't use it, but you can't write C++ programs that avoid any of the other mentioned libraries unless you also restrict yourself to a subset of C++ language features (e.g. no exceptions, no RTTI, no static constructors...).

Libc++ and libstdc++ mangle their symbols differently.  libc++ puts everything in the std::__1 namespace and then says using __1; inside namespace std so that things appear in the source code as being in the std:: namespace, but have different symbol names when linked.  This means that you can link libstdc++ and libc++ in the same program, and you'll get linker errors if you try to pass objects from libraries linked in one version to the other.

>> David
>> With his FreeBSD toolchain hat on
> 
> Thanks for your help, I'm slowly understanding the bigger picture.  Any 
> good documentation out there I can go and read, rather than pester 
> people here?

I've written some documentation on the transition in FreeBSD here:

http://wiki.freebsd.org/NewC++Stack

Slides from my FOSDEM presentation:

https://archive.fosdem.org/2012/schedule/event/399/108_BSDC++.pdf

Howard's excellent talk about libc++:

http://www.llvm.org/devmtg/2010-11/Hinnant-libcxx.pdf

David

-- Sent from my PDP-11




More information about the cfe-dev mailing list