[PATCH] D53796: [libcxx] Use AS_NEEDED command for linker script inputs

Fangrui Song via Phabricator reviews at reviews.llvm.org
Sun Oct 28 00:37:02 PDT 2018


MaskRay added inline comments.


================
Comment at: libcxx/utils/gen_link_script.py:73
     # information.
-    contents = "INPUT(%s %s)" % (linked_libcxx, ' '.join(public_libs))
+    contents = "INPUT(AS_NEEDED(%s %s))" % (linked_libcxx, ' '.join(public_libs))
     print("GENERATING SCRIPT: '%s' as file %s" % (contents, symlink_file))
----------------
phosek wrote:
> MaskRay wrote:
> > I don't understand the intention here.
> > 
> > If the user passes `-lc++` without `--as-needed` before, the user expects to see a `DT_NEEDED` entry for `libc++.so.1`. But with this change. the `DT_NEEDED` entry will not appear.
> > 
> > (In lld, `libc++abi.so.1` resolves undefined symbols in `libc++.so.1` so it will always be needed (`SharedFile::IsNeeded == true`).)
> Passing `-lc++` doesn't imply `DT_NEEDED` because `-lc++` may refer to different things, for example if you only have static library (i.e. `libc++.a`), passing `-lc++` won't create any `DT_NEEDED` entries.
> 
> Implementation of the library gets to decide whether its ABI requires `DT_NEEDED` for users that do not link in any symbols. This is a worthwhile optimization since the implementation does have any initializer-time side-effects or weak symbol overrides that are intended to affect the behavior of a program that doesn't have an undefined reference to a libc++ or libc++abi.
Sorry if I was not clear.

Say we have `libstdc++.so` (ELF) `libc++.so` (linker script `INPUT(...)`). The current behavior:

* `-lstdc++` => `DT_NEEDED libstdc++.so.6`
* `--as-needed -lstdc++` => `DT_NEEDED` tag is as needed
* `-lc++` => `DT_NEEDED libc++.so.1 & libc++abi.so.1`
* `--as-needed -lc++` => `DT_NEEDED libc++.so.1` is as needed; (in lld (different from ld.bfd and gold), `libc++abi.so.1` will always exist)

With this patch,

`-lc++` will essentially become `--as-needed -lc++`. I think we need convincing arguments why we should diverge.

With lld, you can do this if you really need as-needed tag: `-fuse-ld=lld -stdlib=libc++ -Wl,--as-needed -lc++ -Wl,--no-as-needed`
(`-stdlib=libc++` transforms to a second `-lc++`, but .so with the same soname is just ignored. This observed behavior is different from ld.bfd/gold)

If you want as-needed DT_NEEDED with ld.bfd/gold, I guess you'll have to use -nostdlib++ and link libc++ manually.

If this divergent behavior seems reasonable enough to be hard-coded in clang for some particular toolchain: change clang::driver::toolchains::*::AddCXXStdlibLibArgs to add -Wl,--push-state -Wl,--as-needed -lc++ -Wl,--end-state



Repository:
  rCXX libc++

https://reviews.llvm.org/D53796





More information about the libcxx-commits mailing list