[PATCH] D106703: [libunwind] adds a way to synthesise libgcc

Christopher Di Bella via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 26 13:52:45 PDT 2021


cjdb added a comment.

In D106703#2902097 <https://reviews.llvm.org/D106703#2902097>, @MaskRay wrote:

> I try to play with this patch and run into problems.
> I have a `-DLLVM_TARGETS_TO_BUILD=host -DLIBUNWIND_USE_COMPILER_RT=on -DLIBUNWIND_SYNTH_LIBGCC=x86_64` build at /tmp/out/custom1.
> `synth_libgcc` fails:
>
>   % ninja -C /tmp/out/custom1 synth_libgcc
>   ninja: Entering directory `/tmp/out/custom1'
>   [1/1] cd /tmp/out/custom1/projects/libunwind/src && /usr/bin/cmake -E create_symlink  /tmp/out/custom1/./lib/libgcc.a
>   FAILED: projects/libunwind/src/CMakeFiles/synth_libgcc
>   cd /tmp/out/custom1/projects/libunwind/src && /usr/bin/cmake -E create_symlink  /tmp/out/custom1/./lib/libgcc.a
>   ...
>
> `LIBUNWIND_BUILTINS_LIBRARY` is empty in my build, so my libunwind.so.1.0 doesn't have builtins symbols.
> `if (LIBUNWIND_SUPPORTS_NOSTDLIBXX_FLAG OR LIBUNWIND_SUPPORTS_NODEFAULTLIBS_FLAG)` evaluates to true.

LIBUNWIND_BUILTINS_LIBRARY may require you to do a two stage build but this is related to the pre-existing LIBUNWIND_USE_COMPILER_RT option, not because of any changes in this patch.  Stage1: Build clang and compiler-rt. Stage 2: Use the freshly-built clang to compile libunwind.

I’ve added a manual that explains how to build using this feature in the latest revision. PTAL and try again.

> ---
>
> The intention of `LIBUNWIND_BUILTINS_LIBRARY` appears to merge libclang_rt.builtins-* and libunwind into libunwind.so.1.0.
> Then a symlink libgcc_s.so.1 is provided.
>
> But why is --version-script with some `GCC_*` version nodes used?
> libclang_rt.builtins-* and libunwind lack quite a few symbols from a real libgcc_s.so.1.
>
> Many prebuilt applications with a libgcc_s.so.1 DT_NEEDED entry can probably run with the fake libgcc_s.so.1, but many won't.

Our experience with testing this on the whole of Chrome OS suggests that what’s available is sufficient for our use case.

> The reliable way is to rebuild these programs, instead of assuming libunwind+libclang_rt.builtins can provide the compatibility.

We build (almost) everything in Chrome OS from source and have very few vendor binaries so compatibility is not a huge problem for us.

This is mostly a patch to assist distros that can manage their libraries (e.g. Chrome OS, FreeBSD, etc.); it’s not useful for average LLVM users to build for themselves. This feature is opt-in: anyone wanting to use this patch must’ve figured out their compatibility requirements beforehand.

> If such prebuilt programs are relatively few, just drop their symbol versioning (`.gnu.version*` sections and `DT_GNU_VER*` dynamic tags)
>
>   cp in.so out.so
>   r2 -wqc '/x feffff6f @ section..dynamic; w0 8 @ hit0_0' out.so
>   llvm-objcopy -R .gnu.version out.so
>
>
>
> ---
>
>> libunwind/gcc_s-i386.ver
>> `__dlopen`
>
> A version script only affects defined symbols. Patterns like `__dlopen` are not defined and should be removed.

Thanks for noticing, I’ll audit the version script again to remove symbols not provided by compiler-rt. I’ll need a day or so to look into this as I’ll be testing this on Chrome OS CQ before pushing here.

>> `} Unwind_Only;`
>
> The syntax is completed ignored in GNU ld and ld.lld. There is no dependency. Just use `};`
>
> You can remove `global:`. It is ignored.

Thanks for noting this. My understanding of the ld documentation <https://sourceware.org/binutils/docs/ld/VERSION.html> suggests that we should beep both of these. I’ll play with stuff and report back, but this will require at least 48h.

> ---
>
>> Enabling libunwind as a replacement for libgcc on Linux has proven to be challenging since libgcc_s.so is a required dependency in the Linux standard base.
>> https://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/libgcc-s.html
>
> The latest version is 5 which is available on https://refspecs.linuxfoundation.org/lsb.shtml

Thanks, but LSB 5 still has the same requirements.

> ---
>
>> For example, the function __GI___backtrace eventually makes its way to a hardcoded dlopen to libgcc_s' _Unwind_Backtrace. Since libgcc and libunwind have the same ABI, but different implementations, the two libraries end up cross-talking, which ultimately results in a segfault.
>
> POSIX does not require that `pthread_cancel` unwinds the stack and executes landing pads (usually local variable destructors from -fexceptions C++ code).
> glibc and FreeBSD implementations provide the feature. musl doesn't.
>
> My opinion is that this is an unneeded feature. The landing pad execution doesn't help a lot of -fno-exceptions code anyway.
>
> If you can patch glibc, you may just drop the ` __libc_dlopen (LIBGCC_S_SO);` and dlsym `_Unwind_*` code.
> Then your glibc will not dlopen libgcc.so.1, and the problem will be solved.

The POSIX spec isn’t relevant for applications that are already dependent on glibc behaviour. The commit message shows an example calling the backtrace function, which isn’t pthread-related. LSB requirement also makes it a non-starter for a glibc patch, and use of `-static-libgcc` will still require a `dlopen`.

Please keep in mind that this patch isn’t for mainstream developers, but for distro managers who are looking to completely replace libgcc in their system.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D106703/new/

https://reviews.llvm.org/D106703



More information about the llvm-commits mailing list