[llvm-dev] Providing __dso_handle in LLVM

Petr Hosek via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 1 20:47:39 PDT 2017

This is a followup to the discussion that started in D28791. To provide the
context, we need a way to provide __dso_handle in Fuchsia. __dso_handle
symbol is mandated by C++ ABI with a value which is an address in one of
the object's segments, and as such this symbol has to be included
statically and cannot be a part of a shared library. Different systems
provide it differently:

1. On GNU/Linux systems, it's defined in crtbegin.o which is provided by
3. On Android, it's defined in crtbegin.o provided by the Bionic C library.
3. FreeBSD/OpenBSD/NetBSD provide crtbegin.o as part of the system.
4. On macOS, __dso_handle is generated by the linker.

We don't think __dso_handle should be provided by the C library. The name
__dso_handle is not part of the ABI contract with the C library, it's
entirely a name chosen by the C++ ABI. Since C++ front-end defines the
reference to __dso_handle, it should be the compiler that provides the
definition of it somewhere. The reason GCC defines it in crtbegin.o is
purely pragmatic; crtbegin.o is an object file that's already linked into
every shared library and every executable, although there's no principled
reason for __dso_handle to be defined there.

>From the layering point of view, __dso_handle really belongs in libc++abi.
However, for implementation reasons it needs to be included statically into
each final link (whether executable or shared library), even when libc++abi
is built as a shared library.

There several options that we discussed for approaching this:

1. Provide crtbegin.o/crtend.o implementation in compiler-rt. This is the
approach I took in D28791. In Fuchsia, we don't need crtbegin.o/crtend.o at
all, but having these may be useful elsewhere, like LLVM-based Linux
distributions that won't ship libgcc and will need to provide their own
crtbegin.o/crtend.o. However, this approach has been met with a lot of
pushback, where the primary reason has been the fact that
crtbegin.o/crtend.o contain a lot of legacy cruft that may be difficult to
get right across all different systems.

3. Define __dso_handle as part of the Clang builtin library in compiler-rt.
This is the solution we're currently using with a downstream patch (
It works because builtins are already built as a static library, but I'm
not sure whether it's correct from the layering point of view.

3. A cleanest solution from the layering perspective would be add another
archive library to libc++abi, e.g. libc++abi_nonshared.a, that will only
contain the definition of __dso_handle. The ABI linker script that's
generated by libc++ could then include this library into every link. This
work even on systems that already provide __dso_handle. The only aspect
that might be somewhat complicated is the case when the generation of the
ABI linker script, e.g. when the ABI library is statically linked into
libc++. In this case, the libc++abi_nonshared.a would either have to be
linked manually or we would need to generate another linker script.

4. Finally, we could extend LLD to define the __dso_handle symbol,
following the macOS model. This would be a fine solution for us since we
already use LLD as our default linker, but it may not be as clean as other
solutions (i.e. using built-in magic for things that can be done via
general purpose facilities).

Do you have any opinion about these options? I'd like to come up with a
generally acceptable solution and implementing it in upstream rather than
maintaining downstream changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170602/b8038800/attachment.html>

More information about the llvm-dev mailing list