[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