This is an archive of the discontinued LLVM Phabricator instance.

recommend using llvm-ar when finding undefined references and empty archives
ClosedPublic

Authored by inglorion on Mar 15 2017, 4:08 PM.

Details

Summary

When we perform LTO builds with a version of ar that does not
understand LLVM bitcode objects, we end up with undefined references,
because our archive files do not list the bitcode symbols in their
indices. The error messages do not make it clear what the real problem
is. This change adds a note that points out the likely problem and
solution. It is similar in spirit to r282633, but aims to avoid false
positives by only triggering when we see both undefined references and
archives without symbols in their indices.

Fixes PR32281.

Diff Detail

Repository
rL LLVM

Event Timeline

inglorion created this revision.Mar 15 2017, 4:08 PM
inglorion added inline comments.Mar 15 2017, 4:19 PM
ELF/Error.cpp
87 ↗(On Diff #91954)

Since we can't lock a mutex we already hold, exitLld must be called without holding the lock on Mu. This makes the structure of the code here quite unfortunate. Is there a more elegant way to get this to work?

ruiu edited edge metadata.Mar 15 2017, 4:23 PM

I think this patch changes too many files. You could simplify this by constructing an error message string in ArchiveFile::parse (to briefly say something like that "foo.a: no symbol table found. If you are attempting LTO, you need to use llvm-ar instead of ar to create static archives.") and store that to Config. So the code to add parse would be something like

Config->EmptyArchiveErrors.push_back(toString(*this) + ":  symbol table missing ...");

where Config->EmptyArchiveErrors is of std::vector<std::string>.

And then print out these messages in reportUndefined.

@ruiu: Yes, that would be a lot simpler. Let me explain why I did it the way I did it, and then I'll be happy to simplify it if you still feel that's better.

I thought about emitting the message from Relocations.cpp, but then I thought about ErrorLimit. If I emit the note about empty archives after the undefined symbols, it is quite likely that it would not be emitted because the error limit is reached before getting to that point. If I emit the note first, it's easily missed because there may be a whole bunch of undefined reference errors after it. Thinking about that some, I thought it would be most useful if the note is emitted just before lld exits - and that this is actually something that may be more generically useful. That's why I added support for this to Errors. Using this new mechanism, the note is not affected by ErrorLimit and is emitted last, where it should be most effective.

I also thought about reporting the names of the archives in which we found no or empty indices, but my guess is that there isn't a lot of value to that; the most important thing is that this situation may be affecting your build, and switching ar implementations will fix the problem if that's the case. Having the list of file names is more text on the screen, and more memory usage to carry them around, and I didn't feel the benefits outweigh the cost, so I went with a simple boolean.

ruiu added a comment.Mar 15 2017, 4:52 PM

ErrorLimit is 20. Isn't it enough to print out both unresolved symbols and suspicious archive files, is it? If it is not enough, you can print out an error only for the first archive file that doesn't contain a symbol table.

inglorion updated this revision to Diff 91960.Mar 15 2017, 5:05 PM

@ruiu, how is this?

ruiu added inline comments.Mar 15 2017, 5:10 PM
ELF/InputFiles.h
253 ↗(On Diff #91960)

In this way, you need to reset the value in main because LLD should be able to be invoked more than once in the same process if it's used as a library. You want to store this boolean variable to Config.

ELF/Relocations.cpp
619 ↗(On Diff #91960)

You only want to print out this message only once, no?

(nit: remove trailing "\n". I believe message() automatically appends that.)

davide edited edge metadata.Mar 15 2017, 5:52 PM
davide added a subscriber: rnk.

Reid (@rnk) pointed out this comes up during Chromium build so please make sure to verify the output is still reasonable with this patch (if I recall correctly libtool emits something similar (but it's more verbose) and the Chromium folks have to filter it out).

Yes, I'll check Chromium builds once we're happy with the implementation.

ruiu accepted this revision.Mar 16 2017, 3:44 PM

Let's try this. LGTM.

ELF/InputFiles.cpp
565 ↗(On Diff #91963)

Format.

Let's eliminate the local varaible. You could replace NoSymbols with File->symbols().empty(). File->symbols() is cheap so you don't need to save time here.

ELF/Relocations.cpp
623 ↗(On Diff #91963)

Remove the space before ".

This revision is now accepted and ready to land.Mar 16 2017, 3:44 PM
davide added inline comments.Mar 16 2017, 3:46 PM
ELF/InputFiles.cpp
559–565 ↗(On Diff #91963)

Why do you need two different flags?

565 ↗(On Diff #91963)

should live on two different lines, no? (in general, clang-format).

ELF/Relocations.cpp
621 ↗(On Diff #91963)

I'd say "the bitcode files".

davide accepted this revision.Mar 16 2017, 3:46 PM

Other than the comments, this looks good

inglorion added inline comments.Mar 16 2017, 4:19 PM
ELF/InputFiles.cpp
559–565 ↗(On Diff #91963)

By "two different flags" do you mean NoSymbols and ArchiveWithoutSymbolsSeen? I'll get rid of that by following ruiu's suggestion.

565 ↗(On Diff #91963)

W.r.t. "two different lines": that's what I thought, too, but clang-format actually changed it to be one line. Shall I just go ahead and change it back to two lines?

ELF/Relocations.cpp
621 ↗(On Diff #91963)

Hmm, yeah. I added the message because I ran into trouble with bitcode files, but it really is a more general situation, which is why I went with "object files" in the message. Is it ok to leave that as-is or shall I reword the message to something like "This can happen when creating archives with bitcode files (such as created by -flto) using a version of ar that does not know how to index those"?

ruiu added inline comments.Mar 16 2017, 4:28 PM
ELF/InputFiles.cpp
565 ↗(On Diff #91963)

You want to make sure that you are using the LLVM style when formatting it with clang-format. Clang-format reflowed this line to use two lines for me.

inglorion updated this revision to Diff 92202.Mar 17 2017, 2:13 PM

clang-format done right and removed NoSymbols local

ruiu added a comment.Mar 17 2017, 2:16 PM

Still LGTM

In D31011#704298, @ruiu wrote:

Still LGTM

Same.

Closed by commit rL298124 (authored by inglorion). · Explain WhyMar 17 2017, 2:45 PM
This revision was automatically updated to reflect the committed changes.