[PATCH] D32721: Accept archive files with no symbol table instad of warning on them.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 12:00:05 PDT 2017


LGTM

Rui Ueyama via Phabricator <reviews at reviews.llvm.org> writes:

> ruiu updated this revision to Diff 97500.
> ruiu added a comment.
>
> - Instantiate Archive only once.
>
>
> https://reviews.llvm.org/D32721
>
> Files:
>   lld/ELF/Config.h
>   lld/ELF/Driver.cpp
>   lld/ELF/InputFiles.cpp
>   lld/ELF/InputFiles.h
>   lld/ELF/Relocations.cpp
>   lld/test/ELF/lto/archive-no-index.ll
>
> Index: lld/test/ELF/lto/archive-no-index.ll
> ===================================================================
> --- lld/test/ELF/lto/archive-no-index.ll
> +++ lld/test/ELF/lto/archive-no-index.ll
> @@ -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"
> Index: lld/ELF/Relocations.cpp
> ===================================================================
> --- lld/ELF/Relocations.cpp
> +++ lld/ELF/Relocations.cpp
> @@ -694,17 +694,6 @@
>      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;
> -    }
>    }
>  }
>  
> Index: lld/ELF/InputFiles.h
> ===================================================================
> --- lld/ELF/InputFiles.h
> +++ lld/ELF/InputFiles.h
> @@ -239,7 +239,7 @@
>  // 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();
>  
> Index: lld/ELF/InputFiles.cpp
> ===================================================================
> --- lld/ELF/InputFiles.cpp
> +++ lld/ELF/InputFiles.cpp
> @@ -596,17 +596,13 @@
>    }
>  }
>  
> -template <class ELFT> void ArchiveFile::parse() {
> -  File = check(Archive::create(MB),
> -               MB.getBufferIdentifier() + ": failed to parse archive");
> +ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
> +    : InputFile(ArchiveKind, File->getMemoryBufferRef()),
> +      File(std::move(File)) {}
>  
> -  // Read the symbol table to construct Lazy objects.
> -  for (const Archive::Symbol &Sym : File->symbols()) {
> +template <class ELFT> void ArchiveFile::parse() {
> +  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.
> Index: lld/ELF/Driver.cpp
> ===================================================================
> --- lld/ELF/Driver.cpp
> +++ lld/ELF/Driver.cpp
> @@ -171,14 +171,31 @@
>    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);
> Index: lld/ELF/Config.h
> ===================================================================
> --- lld/ELF/Config.h
> +++ lld/ELF/Config.h
> @@ -99,7 +99,6 @@
>    std::vector<SymbolVersion> VersionScriptLocals;
>    std::vector<uint8_t> BuildIdVector;
>    bool AllowMultipleDefinition;
> -  bool ArchiveWithoutSymbolsSeen = false;
>    bool AsNeeded = false;
>    bool Bsymbolic;
>    bool BsymbolicFunctions;


More information about the llvm-commits mailing list