[llvm-dev] [RFC] Adding a new option to lld to make it easy to maintain compatibility with other linkers

Rui Ueyama via llvm-dev llvm-dev at lists.llvm.org
Wed Apr 4 15:46:38 PDT 2018


Hi guys,

I'd like to propose a new lld command line option,
--check-library-dependency. We already have a patch (
https://reviews.llvm.org/D45195), and I'm satisfied with it, but I'd like
to get feedback from those who are using lld before submitting.

--check-library-dependency is an option to prevent an undefined reference
from fetching an archive member written earlier in the command line. It can
be used to keep your program compatible with GNU linkers after you switch
to lld. I'll explain the feature and why you may find it useful below.

lld's symbol resolution semantics is more relaxed than traditional Unix
linkers. For example,

  ld.lld foo.a bar.o

succeeds even if bar.o contains an undefined symbol that have to be
resolved by some object file in foo.a. Traditional Unix linkers don't allow
this kind of backward reference, as they visit each file only once from
left to right in the command line while resolving all undefined symbols at
the moment of visiting.

In the above case, since there's no undefined symbol when a linker visits
foo.a, no files are pulled out from foo.a, and because the linker forgets
about foo.a after visiting, it can't resolve undefined symbols in bar.o
that could have been resolved otherwise.

That lld accepts more relaxed form means that (besides it'd make more
sense) you can accidentally write a command line or a build file that works
only with lld, even if you have a plan to distribute it to wider users who
may be using GNU linkers. With --check-library-dependency, you can detect a
library order that doesn't work with other Unix linkers.

The option is also useful to detect cyclic dependencies between static
archives. Again, lld accepts

  ld.lld foo.a bar.a

even if foo.a and bar.a depend on each other. With
--check-library-dependency, it is handled as an error.

Here is how the option works. We assign a group ID to each file. A file
with a smaller group ID can pull out object files from an archive file with
an equal or greater group ID. Otherwise, it is a reverse dependency and an
error.

A file outside --{start,end}-group gets a fresh ID when instantiated. All
files within the same --{start,end}-group get the same group ID. E.g.

  ld.lld A B --start-group C D --end-group E

A and B form group 0. C, D and their member object files form group 1. E
forms group 2. I think that you can see how this group assignment rule
simulates the traditional linker's semantics.

I think this is a reasonable option to add. What do you guys think?

Rui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180404/35cc30db/attachment.html>


More information about the llvm-dev mailing list