forked from OSchip/llvm-project
Accept archive files with no symbol table instad of warning on them.
It seems virtually everyone who tries to do LTO build with Clang and LLD was hit by a mistake to forget using llvm-ar command to create archive files. I wasn't an exception. Since this is an annoying common issue, it is probably better to handle that gracefully rather than reporting an error and tell the user to redo build with different configuration. Differential Revision: https://reviews.llvm.org/D32721 llvm-svn: 302083
This commit is contained in:
parent
1f8b73d15c
commit
fd7deda57a
|
@ -99,7 +99,6 @@ struct Configuration {
|
|||
std::vector<SymbolVersion> VersionScriptLocals;
|
||||
std::vector<uint8_t> BuildIdVector;
|
||||
bool AllowMultipleDefinition;
|
||||
bool ArchiveWithoutSymbolsSeen = false;
|
||||
bool AsNeeded = false;
|
||||
bool Bsymbolic;
|
||||
bool BsymbolicFunctions;
|
||||
|
|
|
@ -171,14 +171,31 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
|
|||
case file_magic::unknown:
|
||||
readLinkerScript(MBRef);
|
||||
return;
|
||||
case file_magic::archive:
|
||||
case file_magic::archive: {
|
||||
// Handle -whole-archive.
|
||||
if (InWholeArchive) {
|
||||
for (MemoryBufferRef MB : getArchiveMembers(MBRef))
|
||||
Files.push_back(createObjectFile(MB, Path));
|
||||
return;
|
||||
}
|
||||
Files.push_back(make<ArchiveFile>(MBRef));
|
||||
|
||||
std::unique_ptr<Archive> File =
|
||||
check(Archive::create(MBRef), Path + ": failed to parse archive");
|
||||
|
||||
// If an archive file has no symbol table, it is likely that a user
|
||||
// is attempting LTO and using a default ar command that doesn't
|
||||
// understand the LLVM bitcode file. It is a pretty common error, so
|
||||
// we'll handle it as if it had a symbol table.
|
||||
if (!File->hasSymbolTable()) {
|
||||
for (MemoryBufferRef MB : getArchiveMembers(MBRef))
|
||||
Files.push_back(make<LazyObjectFile>(MB));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the regular case.
|
||||
Files.push_back(make<ArchiveFile>(std::move(File)));
|
||||
return;
|
||||
}
|
||||
case file_magic::elf_shared_object:
|
||||
if (Config->Relocatable) {
|
||||
error("attempted static link of dynamic object " + Path);
|
||||
|
|
|
@ -596,17 +596,13 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
|
|||
}
|
||||
}
|
||||
|
||||
ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
|
||||
: InputFile(ArchiveKind, File->getMemoryBufferRef()),
|
||||
File(std::move(File)) {}
|
||||
|
||||
template <class ELFT> void ArchiveFile::parse() {
|
||||
File = check(Archive::create(MB),
|
||||
MB.getBufferIdentifier() + ": failed to parse archive");
|
||||
|
||||
// Read the symbol table to construct Lazy objects.
|
||||
for (const Archive::Symbol &Sym : File->symbols()) {
|
||||
for (const Archive::Symbol &Sym : File->symbols())
|
||||
Symtab<ELFT>::X->addLazyArchive(this, Sym);
|
||||
}
|
||||
|
||||
if (File->symbols().begin() == File->symbols().end())
|
||||
Config->ArchiveWithoutSymbolsSeen = true;
|
||||
}
|
||||
|
||||
// Returns a buffer pointing to a member file containing a given symbol.
|
||||
|
|
|
@ -239,7 +239,7 @@ private:
|
|||
// An ArchiveFile object represents a .a file.
|
||||
class ArchiveFile : public InputFile {
|
||||
public:
|
||||
explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
|
||||
explicit ArchiveFile(std::unique_ptr<Archive> &&File);
|
||||
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
|
||||
template <class ELFT> void parse();
|
||||
|
||||
|
|
|
@ -694,17 +694,6 @@ static void reportUndefined(SymbolBody &Sym, InputSectionBase &S,
|
|||
warn(Msg);
|
||||
} else {
|
||||
error(Msg);
|
||||
|
||||
if (Config->ArchiveWithoutSymbolsSeen) {
|
||||
message("At least one archive listed no symbols in its index."
|
||||
" This can happen when creating archives with a version"
|
||||
" of ar that does not understand the object files in"
|
||||
" the archive. For example, if you are using LLVM"
|
||||
" bitcode objects (such as created by -flto), you may"
|
||||
" need to use llvm-ar or GNU ar with a plugin.");
|
||||
// Reset to false so that we print the message only once.
|
||||
Config->ArchiveWithoutSymbolsSeen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,29 +4,15 @@
|
|||
; encountered an empty archive index and undefined references (to prevent
|
||||
; noisy false alarms).
|
||||
|
||||
; RUN: rm -fr %T/archive-no-index
|
||||
; RUN: mkdir %T/archive-no-index
|
||||
; RUN: llvm-as %S/Inputs/archive.ll -o %T/archive-no-index/f.o
|
||||
; RUN: llvm-ar cr %T/archive-no-index/libf.a
|
||||
; RUN: llvm-ar qS %T/archive-no-index/libf.a %T/archive-no-index/f.o
|
||||
; RUN: llvm-as %s -o %t.o
|
||||
; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
|
||||
; RUN: 2>&1 | FileCheck --check-prefix=NOTE %s
|
||||
; RUN: llvm-as -o %t1.o %s
|
||||
; RUN: llvm-as -o %t2.o %S/Inputs/archive.ll
|
||||
|
||||
; RUN: llvm-ar crs %T/archive-no-index/libfs.a %T/archive-no-index/f.o
|
||||
; RUN: ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
|
||||
; RUN: %T/archive-no-index/libfs.a
|
||||
; RUN: rm -f %t1.a %t2.a
|
||||
; RUN: llvm-ar crS %t1.a %t2.o
|
||||
; RUN: llvm-ar crs %t2.a %t2.o
|
||||
|
||||
; RUN: llvm-as %S/Inputs/archive-3.ll -o %T/archive-no-index/foo.o
|
||||
; RUN: llvm-ar crs %T/archive-no-index/libfoo.a %T/archive-no-index/foo.o
|
||||
; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libfoo.a \
|
||||
; RUN: 2>&1 | FileCheck --check-prefix=NO-NOTE %s
|
||||
|
||||
; NOTE: undefined symbol: f
|
||||
; NOTE: archive listed no symbols
|
||||
|
||||
; NO-NOTE: undefined symbol: f
|
||||
; NO-NOTE-NOT: archive listed no symbols
|
||||
; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t1.a
|
||||
; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t2.a
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
Loading…
Reference in New Issue