[lld] r370487 - [lld-link] implement -start-lib and -end-lib

Vlad Tsyrklevich via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 30 16:24:12 PDT 2019


I've reverted this change as it was causing ASan/MSan failures like the
following:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/34761/steps/check-lld%20asan/logs/stdio

On Fri, Aug 30, 2019 at 9:48 AM Bob Haarman via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: inglorion
> Date: Fri Aug 30 09:50:10 2019
> New Revision: 370487
>
> URL: http://llvm.org/viewvc/llvm-project?rev=370487&view=rev
> Log:
> [lld-link] implement -start-lib and -end-lib
>
> Summary:
> This implements -start-lib and -end-lib flags for lld-link, analogous
> to the similarly named options in ld.lld. Object files after
> -start-lib are included in the link only when needed to resolve
> undefined symbols. The -end-lib flag goes back to the normal behavior
> of always including object files in the link. This mimics the
> semantics of static libraries, but without needing to actually create
> the archive file.
>
> Reviewers: ruiu, smeenai, MaskRay
>
> Reviewed By: ruiu, MaskRay
>
> Subscribers: akhuang, llvm-commits
>
> Tags: #llvm
>
> Differential Revision: https://reviews.llvm.org/D66848
>
> Added:
>     lld/trunk/test/COFF/Inputs/start-lib1.ll
>     lld/trunk/test/COFF/Inputs/start-lib2.ll
>     lld/trunk/test/COFF/start-lib-cmd-diagnostics.ll
>     lld/trunk/test/COFF/start-lib.ll
> Modified:
>     lld/trunk/COFF/DebugTypes.cpp
>     lld/trunk/COFF/Driver.cpp
>     lld/trunk/COFF/Driver.h
>     lld/trunk/COFF/InputFiles.cpp
>     lld/trunk/COFF/InputFiles.h
>     lld/trunk/COFF/Options.td
>     lld/trunk/COFF/SymbolTable.cpp
>     lld/trunk/COFF/SymbolTable.h
>     lld/trunk/COFF/Symbols.cpp
>     lld/trunk/COFF/Symbols.h
>     lld/trunk/COFF/Writer.cpp
>
> Modified: lld/trunk/COFF/DebugTypes.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DebugTypes.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/DebugTypes.cpp (original)
> +++ lld/trunk/COFF/DebugTypes.cpp Fri Aug 30 09:50:10 2019
> @@ -231,7 +231,7 @@ void TypeServerSource::enqueue(const Obj
>    if (!it.second)
>      return; // another OBJ already scheduled this PDB for load
>
> -  driver->enqueuePath(*p, false);
> +  driver->enqueuePath(*p, false, false);
>  }
>
>  // Create an instance of TypeServerSource or an error string if the PDB
> couldn't
>
> Modified: lld/trunk/COFF/Driver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Driver.cpp (original)
> +++ lld/trunk/COFF/Driver.cpp Fri Aug 30 09:50:10 2019
> @@ -170,7 +170,7 @@ MemoryBufferRef LinkerDriver::takeBuffer
>  }
>
>  void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
> -                             bool wholeArchive) {
> +                             bool wholeArchive, bool lazy) {
>    StringRef filename = mb->getBufferIdentifier();
>
>    MemoryBufferRef mbref = takeBuffer(std::move(mb));
> @@ -195,11 +195,17 @@ void LinkerDriver::addBuffer(std::unique
>      symtab->addFile(make<ArchiveFile>(mbref));
>      break;
>    case file_magic::bitcode:
> -    symtab->addFile(make<BitcodeFile>(mbref, "", 0));
> +    if (lazy)
> +      symtab->addFile(make<LazyObjFile>(mbref));
> +    else
> +      symtab->addFile(make<BitcodeFile>(mbref, "", 0));
>      break;
>    case file_magic::coff_object:
>    case file_magic::coff_import_library:
> -    symtab->addFile(make<ObjFile>(mbref));
> +    if (lazy)
> +      symtab->addFile(make<LazyObjFile>(mbref));
> +    else
> +      symtab->addFile(make<ObjFile>(mbref));
>      break;
>    case file_magic::pdb:
>      loadTypeServerSource(mbref);
> @@ -220,7 +226,7 @@ void LinkerDriver::addBuffer(std::unique
>    }
>  }
>
> -void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) {
> +void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool
> lazy) {
>    auto future =
>        std::make_shared<std::future<MBErrPair>>(createFutureForFile(path));
>    std::string pathStr = path;
> @@ -240,7 +246,7 @@ void LinkerDriver::enqueuePath(StringRef
>        else
>          error(msg + "; did you mean '" + nearest + "'");
>      } else
> -      driver->addBuffer(std::move(mbOrErr.first), wholeArchive);
> +      driver->addBuffer(std::move(mbOrErr.first), wholeArchive, lazy);
>    });
>  }
>
> @@ -359,7 +365,7 @@ void LinkerDriver::parseDirectives(Input
>        break;
>      case OPT_defaultlib:
>        if (Optional<StringRef> path = findLib(arg->getValue()))
> -        enqueuePath(*path, false);
> +        enqueuePath(*path, false, false);
>        break;
>      case OPT_entry:
>        config->entry = addUndefined(mangle(arg->getValue()));
> @@ -1553,19 +1559,45 @@ void LinkerDriver::link(ArrayRef<const c
>      return false;
>    };
>
> -  // Create a list of input files. Files can be given as arguments
> -  // for /defaultlib option.
> -  for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file))
> -    if (Optional<StringRef> path = findFile(arg->getValue()))
> -      enqueuePath(*path, isWholeArchive(*path));
> +  // Create a list of input files. These can be given as OPT_INPUT options
> +  // and OPT_wholearchive_file options, and we also need to track
> OPT_start_lib
> +  // and OPT_end_lib.
> +  bool inLib = false;
> +  for (auto *arg : args) {
> +    switch (arg->getOption().getID()) {
> +    case OPT_end_lib:
> +      if (!inLib)
> +        error("stray " + arg->getSpelling());
> +      inLib = false;
> +      break;
> +    case OPT_start_lib:
> +      if (inLib)
> +        error("nested " + arg->getSpelling());
> +      inLib = true;
> +      break;
> +    case OPT_wholearchive_file:
> +      if (Optional<StringRef> path = findFile(arg->getValue()))
> +        enqueuePath(*path, true, inLib);
> +      break;
> +    case OPT_INPUT:
> +      if (Optional<StringRef> path = findFile(arg->getValue()))
> +        enqueuePath(*path, isWholeArchive(*path), inLib);
> +      break;
> +    default:
> +      // Ignore other options.
> +      break;
> +    }
> +  }
>
> +  // Process files specified as /defaultlib. These should be enequeued
> after
> +  // other files, which is why they are in a separate loop.
>    for (auto *arg : args.filtered(OPT_defaultlib))
>      if (Optional<StringRef> path = findLib(arg->getValue()))
> -      enqueuePath(*path, false);
> +      enqueuePath(*path, false, false);
>
>    // Windows specific -- Create a resource file containing a manifest
> file.
>    if (config->manifest == Configuration::Embed)
> -    addBuffer(createManifestRes(), false);
> +    addBuffer(createManifestRes(), false, false);
>
>    // Read all input files given via the command line.
>    run();
> @@ -1782,7 +1814,7 @@ void LinkerDriver::link(ArrayRef<const c
>    if (args.hasArg(OPT_include_optional)) {
>      // Handle /includeoptional
>      for (auto *arg : args.filtered(OPT_include_optional))
> -      if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue())))
> +      if (dyn_cast_or_null<LazyArchive>(symtab->find(arg->getValue())))
>          addUndefined(arg->getValue());
>      while (run());
>    }
>
> Modified: lld/trunk/COFF/Driver.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Driver.h (original)
> +++ lld/trunk/COFF/Driver.h Fri Aug 30 09:50:10 2019
> @@ -77,7 +77,7 @@ public:
>
>    MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
>
> -  void enqueuePath(StringRef path, bool wholeArchive);
> +  void enqueuePath(StringRef path, bool wholeArchive, bool lazy);
>
>  private:
>    std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
> @@ -124,7 +124,8 @@ private:
>    StringRef findDefaultEntry();
>    WindowsSubsystem inferSubsystem();
>
> -  void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive);
> +  void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,
> +                 bool lazy);
>    void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
>                          StringRef parentName, uint64_t offsetInArchive);
>
>
> Modified: lld/trunk/COFF/InputFiles.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/InputFiles.cpp (original)
> +++ lld/trunk/COFF/InputFiles.cpp Fri Aug 30 09:50:10 2019
> @@ -73,6 +73,10 @@ static void checkAndSetWeakAlias(SymbolT
>    }
>  }
>
> +static bool ignoredSymbolName(StringRef name) {
> +  return name == "@feat.00" || name == "@comp.id";
> +}
> +
>  ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
>
>  void ArchiveFile::parse() {
> @@ -81,7 +85,7 @@ void ArchiveFile::parse() {
>
>    // Read the symbol table to construct Lazy objects.
>    for (const Archive::Symbol &sym : file->symbols())
> -    symtab->addLazy(this, sym);
> +    symtab->addLazyArchive(this, sym);
>  }
>
>  // Returns a buffer pointing to a member file containing a given symbol.
> @@ -116,6 +120,49 @@ std::vector<MemoryBufferRef> getArchiveM
>    return v;
>  }
>
> +void LazyObjFile::fetch() {
> +  if (mb.getBuffer().empty())
> +    return;
> +
> +  InputFile *file;
> +  if (isBitcode(mb))
> +    file = make<BitcodeFile>(mb, "", 0, std::move(symbols));
> +  else
> +    file = make<ObjFile>(mb, std::move(symbols));
> +  mb = {};
> +  symtab->addFile(file);
> +}
> +
> +void LazyObjFile::parse() {
> +  if (isBitcode(this->mb)) {
> +    // Bitcode file.
> +    std::unique_ptr<lto::InputFile> obj =
> +        CHECK(lto::InputFile::create(this->mb), this);
> +    for (const lto::InputFile::Symbol &sym : obj->symbols()) {
> +      if (!sym.isUndefined())
> +        symtab->addLazyObject(this, sym.getName());
> +    }
> +    return;
> +  }
> +
> +  // Native object file.
> +  COFFObjectFile *coffObj =
> +      dyn_cast<COFFObjectFile>(CHECK(createBinary(mb), this).get());
> +  uint32_t numSymbols = coffObj->getNumberOfSymbols();
> +  for (uint32_t i = 0; i < numSymbols; ++i) {
> +    COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
> +    if (coffSym.isUndefined() || !coffSym.isExternal() ||
> +        coffSym.isWeakExternal())
> +      continue;
> +    StringRef name;
> +    coffObj->getSymbolName(coffSym, name);
> +    if (coffSym.isAbsolute() && ignoredSymbolName(name))
> +      continue;
> +    symtab->addLazyObject(this, name);
> +    i += coffSym.getNumberOfAuxSymbols();
> +  }
> +}
> +
>  void ObjFile::parse() {
>    // Parse a memory buffer as a COFF file.
>    std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
> @@ -526,13 +573,11 @@ Optional<Symbol *> ObjFile::createDefine
>    if (sym.isAbsolute()) {
>      StringRef name = getName();
>
> -    // Skip special symbols.
> -    if (name == "@comp.id")
> -      return nullptr;
> -    if (name == "@feat.00") {
> +    if (name == "@feat.00")
>        feat00Flags = sym.getValue();
> +    // Skip special symbols.
> +    if (ignoredSymbolName(name))
>        return nullptr;
> -    }
>
>      if (sym.isExternal())
>        return symtab->addAbsolute(name, sym);
> @@ -782,8 +827,9 @@ void ImportFile::parse() {
>  }
>
>  BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
> -                         uint64_t offsetInArchive)
> -    : InputFile(BitcodeKind, mb) {
> +                         uint64_t offsetInArchive,
> +                         std::vector<Symbol *> &&symbols)
> +    : InputFile(BitcodeKind, mb), symbols(std::move(symbols)) {
>    std::string path = mb.getBufferIdentifier().str();
>    if (config->thinLTOIndexOnly)
>      path = replaceThinLTOSuffix(mb.getBufferIdentifier());
>
> Modified: lld/trunk/COFF/InputFiles.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/InputFiles.h (original)
> +++ lld/trunk/COFF/InputFiles.h Fri Aug 30 09:50:10 2019
> @@ -14,6 +14,7 @@
>  #include "llvm/ADT/ArrayRef.h"
>  #include "llvm/ADT/DenseMap.h"
>  #include "llvm/ADT/DenseSet.h"
> +#include "llvm/BinaryFormat/Magic.h"
>  #include "llvm/DebugInfo/CodeView/TypeRecord.h"
>  #include "llvm/LTO/LTO.h"
>  #include "llvm/Object/Archive.h"
> @@ -55,7 +56,13 @@ class TpiSource;
>  // The root class of input files.
>  class InputFile {
>  public:
> -  enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
> +  enum Kind {
> +    ArchiveKind,
> +    ObjectKind,
> +    LazyObjectKind,
> +    ImportKind,
> +    BitcodeKind
> +  };
>    Kind kind() const { return fileKind; }
>    virtual ~InputFile() {}
>
> @@ -102,10 +109,28 @@ private:
>    llvm::DenseSet<uint64_t> seen;
>  };
>
> +// .obj or .o file between -start-lib and -end-lib.
> +class LazyObjFile : public InputFile {
> +public:
> +  explicit LazyObjFile(MemoryBufferRef m) : InputFile(LazyObjectKind, m)
> {}
> +  static bool classof(const InputFile *f) {
> +    return f->kind() == LazyObjectKind;
> +  }
> +  // Makes this object file part of the link.
> +  void fetch();
> +  // Adds the symbols in this file to the symbol table as LazyObject
> symbols.
> +  void parse() override;
> +
> +private:
> +  std::vector<Symbol *> symbols;
> +};
> +
>  // .obj or .o file. This may be a member of an archive file.
>  class ObjFile : public InputFile {
>  public:
>    explicit ObjFile(MemoryBufferRef m) : InputFile(ObjectKind, m) {}
> +  explicit ObjFile(MemoryBufferRef m, std::vector<Symbol *> &&symbols)
> +      : InputFile(ObjectKind, m), symbols(std::move(symbols)) {}
>    static bool classof(const InputFile *f) { return f->kind() ==
> ObjectKind; }
>    void parse() override;
>    MachineTypes getMachineType() override;
> @@ -301,7 +326,11 @@ public:
>  class BitcodeFile : public InputFile {
>  public:
>    BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
> -              uint64_t offsetInArchive);
> +              uint64_t offsetInArchive)
> +      : BitcodeFile(mb, archiveName, offsetInArchive, {}) {}
> +  explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName,
> +                       uint64_t offsetInArchive,
> +                       std::vector<Symbol *> &&symbols);
>    static bool classof(const InputFile *f) { return f->kind() ==
> BitcodeKind; }
>    ArrayRef<Symbol *> getSymbols() { return symbols; }
>    MachineTypes getMachineType() override;
> @@ -314,6 +343,10 @@ private:
>    std::vector<Symbol *> symbols;
>  };
>
> +inline bool isBitcode(MemoryBufferRef mb) {
> +  return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
> +}
> +
>  std::string replaceThinLTOSuffix(StringRef path);
>  } // namespace coff
>
>
> Modified: lld/trunk/COFF/Options.td
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Options.td (original)
> +++ lld/trunk/COFF/Options.td Fri Aug 30 09:50:10 2019
> @@ -162,6 +162,8 @@ def help : F<"help">;
>  def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias<help>;
>
>  // LLD extensions
> +def end_lib : F<"end-lib">,
> +  HelpText<"End a grouping of objects that should be treated as if they
> were together in an archive">;
>  def exclude_all_symbols : F<"exclude-all-symbols">;
>  def export_all_symbols : F<"export-all-symbols">;
>  defm demangle : B<"demangle",
> @@ -176,6 +178,8 @@ def pdb_source_path : P<"pdbsourcepath",
>                          "Base path used to make relative source file path
> absolute in PDB">;
>  def rsp_quoting : Joined<["--"], "rsp-quoting=">,
>    HelpText<"Quoting style for response files, 'windows' (default) or
> 'posix'">;
> +def start_lib : F<"start-lib">,
> +  HelpText<"Start a grouping of objects that should be treated as if they
> were together in an archive">;
>  def thinlto_emit_imports_files :
>      F<"thinlto-emit-imports-files">,
>      HelpText<"Emit .imports files with -thinlto-index-only">;
>
> Modified: lld/trunk/COFF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/SymbolTable.cpp (original)
> +++ lld/trunk/COFF/SymbolTable.cpp Fri Aug 30 09:50:10 2019
> @@ -61,6 +61,24 @@ static void errorOrWarn(const Twine &s)
>      error(s);
>  }
>
> +// Causes the file associated with a lazy symbol to be linked in.
> +static void forceLazy(Symbol *s) {
> +  s->pendingArchiveLoad = true;
> +  switch (s->kind()) {
> +  case Symbol::Kind::LazyArchiveKind: {
> +    auto *l = cast<LazyArchive>(s);
> +    l->file->addMember(l->sym);
> +    break;
> +  }
> +  case Symbol::Kind::LazyObjectKind:
> +    cast<LazyObject>(s)->file->fetch();
> +    break;
> +  default:
> +    llvm_unreachable(
> +        "symbol passed to forceLazy is not a LazyArchive or LazyObject");
> +  }
> +}
> +
>  // Returns the symbol in SC whose value is <= Addr that is closest to
> Addr.
>  // This is generally the global variable or function whose definition
> contains
>  // Addr.
> @@ -192,16 +210,15 @@ void SymbolTable::loadMinGWAutomaticImpo
>
>      if (name.startswith("__imp_"))
>        continue;
> -    // If we have an undefined symbol, but we have a Lazy representing a
> -    // symbol we could load from file, make sure to load that.
> -    Lazy *l = dyn_cast_or_null<Lazy>(find(("__imp_" + name).str()));
> -    if (!l || l->pendingArchiveLoad)
> +    // If we have an undefined symbol, but we have a lazy symbol we could
> +    // load, load it.
> +    Symbol *l = find(("__imp_" + name).str());
> +    if (!l || l->pendingArchiveLoad || !l->isLazy())
>        continue;
>
> -    log("Loading lazy " + l->getName() + " from " + l->file->getName() +
> +    log("Loading lazy " + l->getName() + " from " +
> l->getFile()->getName() +
>          " for automatic import");
> -    l->pendingArchiveLoad = true;
> -    l->file->addMember(l->sym);
> +    forceLazy(l);
>    }
>  }
>
> @@ -435,26 +452,22 @@ Symbol *SymbolTable::addUndefined(String
>    Symbol *s;
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(name, f);
> -  if (wasInserted || (isa<Lazy>(s) && isWeakAlias)) {
> +  if (wasInserted || (s->isLazy() && isWeakAlias)) {
>      replaceSymbol<Undefined>(s, name);
>      return s;
>    }
> -  if (auto *l = dyn_cast<Lazy>(s)) {
> -    if (!s->pendingArchiveLoad) {
> -      s->pendingArchiveLoad = true;
> -      l->file->addMember(l->sym);
> -    }
> -  }
> +  if (s->isLazy())
> +    forceLazy(s);
>    return s;
>  }
>
> -void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol &sym) {
> +void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol
> &sym) {
>    StringRef name = sym.getName();
>    Symbol *s;
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(name);
>    if (wasInserted) {
> -    replaceSymbol<Lazy>(s, f, sym);
> +    replaceSymbol<LazyArchive>(s, f, sym);
>      return;
>    }
>    auto *u = dyn_cast<Undefined>(s);
> @@ -464,6 +477,21 @@ void SymbolTable::addLazy(ArchiveFile *f
>    f->addMember(sym);
>  }
>
> +void SymbolTable::addLazyObject(LazyObjFile *f, StringRef n) {
> +  Symbol *s;
> +  bool wasInserted;
> +  std::tie(s, wasInserted) = insert(n, f);
> +  if (wasInserted) {
> +    replaceSymbol<LazyObject>(s, f, n);
> +    return;
> +  }
> +  auto *u = dyn_cast<Undefined>(s);
> +  if (!u || u->weakAlias || s->pendingArchiveLoad)
> +    return;
> +  s->pendingArchiveLoad = true;
> +  f->fetch();
> +}
> +
>  void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) {
>    std::string msg = "duplicate symbol: " + toString(*existing) + " in " +
>                      toString(existing->getFile()) + " and in " +
> @@ -480,7 +508,7 @@ Symbol *SymbolTable::addAbsolute(StringR
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(n, nullptr);
>    s->isUsedInRegularObj = true;
> -  if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
> +  if (wasInserted || isa<Undefined>(s) || s->isLazy())
>      replaceSymbol<DefinedAbsolute>(s, n, sym);
>    else if (!isa<DefinedCOFF>(s))
>      reportDuplicate(s, nullptr);
> @@ -492,7 +520,7 @@ Symbol *SymbolTable::addAbsolute(StringR
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(n, nullptr);
>    s->isUsedInRegularObj = true;
> -  if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
> +  if (wasInserted || isa<Undefined>(s) || s->isLazy())
>      replaceSymbol<DefinedAbsolute>(s, n, va);
>    else if (!isa<DefinedCOFF>(s))
>      reportDuplicate(s, nullptr);
> @@ -504,7 +532,7 @@ Symbol *SymbolTable::addSynthetic(String
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(n, nullptr);
>    s->isUsedInRegularObj = true;
> -  if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
> +  if (wasInserted || isa<Undefined>(s) || s->isLazy())
>      replaceSymbol<DefinedSynthetic>(s, n, c);
>    else if (!isa<DefinedCOFF>(s))
>      reportDuplicate(s, nullptr);
> @@ -560,7 +588,7 @@ Symbol *SymbolTable::addImportData(Strin
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(n, nullptr);
>    s->isUsedInRegularObj = true;
> -  if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
> +  if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
>      replaceSymbol<DefinedImportData>(s, n, f);
>      return s;
>    }
> @@ -575,7 +603,7 @@ Symbol *SymbolTable::addImportThunk(Stri
>    bool wasInserted;
>    std::tie(s, wasInserted) = insert(name, nullptr);
>    s->isUsedInRegularObj = true;
> -  if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
> +  if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
>      replaceSymbol<DefinedImportThunk>(s, name, id, machine);
>      return s;
>    }
> @@ -589,9 +617,12 @@ void SymbolTable::addLibcall(StringRef n
>    if (!sym)
>      return;
>
> -  if (Lazy *l = dyn_cast<Lazy>(sym)) {
> +  if (auto *l = dyn_cast<LazyArchive>(sym)) {
>      MemoryBufferRef mb = l->getMemberBuffer();
> -    if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode)
> +    if (isBitcode(mb))
> +      addUndefined(sym->getName());
> +  } else if (LazyObject *o = dyn_cast<LazyObject>(sym)) {
> +    if (isBitcode(o->file->mb))
>        addUndefined(sym->getName());
>    }
>  }
>
> Modified: lld/trunk/COFF/SymbolTable.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/SymbolTable.h (original)
> +++ lld/trunk/COFF/SymbolTable.h Fri Aug 30 09:50:10 2019
> @@ -29,7 +29,7 @@ class Defined;
>  class DefinedAbsolute;
>  class DefinedRegular;
>  class DefinedRelative;
> -class Lazy;
> +class LazyArchive;
>  class SectionChunk;
>  class Symbol;
>
> @@ -86,7 +86,8 @@ public:
>    Symbol *addAbsolute(StringRef n, uint64_t va);
>
>    Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias);
> -  void addLazy(ArchiveFile *f, const Archive::Symbol &sym);
> +  void addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym);
> +  void addLazyObject(LazyObjFile *f, StringRef n);
>    Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
>    Symbol *addRegular(InputFile *f, StringRef n,
>                       const llvm::object::coff_symbol_generic *s = nullptr,
>
> Modified: lld/trunk/COFF/Symbols.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Symbols.cpp (original)
> +++ lld/trunk/COFF/Symbols.cpp Fri Aug 30 09:50:10 2019
> @@ -61,7 +61,9 @@ StringRef Symbol::getName() {
>  InputFile *Symbol::getFile() {
>    if (auto *sym = dyn_cast<DefinedCOFF>(this))
>      return sym->file;
> -  if (auto *sym = dyn_cast<Lazy>(this))
> +  if (auto *sym = dyn_cast<LazyArchive>(this))
> +    return sym->file;
> +  if (auto *sym = dyn_cast<LazyObject>(this))
>      return sym->file;
>    return nullptr;
>  }
> @@ -119,7 +121,7 @@ Defined *Undefined::getWeakAlias() {
>    return nullptr;
>  }
>
> -MemoryBufferRef Lazy::getMemberBuffer() {
> +MemoryBufferRef LazyArchive::getMemberBuffer() {
>    Archive::Child c =
>      CHECK(sym.getMember(),
>            "could not get the member for symbol " + toCOFFString(sym));
>
> Modified: lld/trunk/COFF/Symbols.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Symbols.h (original)
> +++ lld/trunk/COFF/Symbols.h Fri Aug 30 09:50:10 2019
> @@ -59,7 +59,8 @@ public:
>      DefinedSyntheticKind,
>
>      UndefinedKind,
> -    LazyKind,
> +    LazyArchiveKind,
> +    LazyObjectKind,
>
>      LastDefinedCOFFKind = DefinedCommonKind,
>      LastDefinedKind = DefinedSyntheticKind,
> @@ -79,6 +80,10 @@ public:
>    // after calling markLive.
>    bool isLive() const;
>
> +  bool isLazy() const {
> +    return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind;
> +  }
> +
>  protected:
>    friend SymbolTable;
>    explicit Symbol(Kind k, StringRef n = "")
> @@ -256,26 +261,29 @@ private:
>  // This class represents a symbol defined in an archive file. It is
>  // created from an archive file header, and it knows how to load an
>  // object file from an archive to replace itself with a defined
> -// symbol. If the resolver finds both Undefined and Lazy for
> -// the same name, it will ask the Lazy to load a file.
> -class Lazy : public Symbol {
> +// symbol. If the resolver finds both Undefined and LazyArchive for
> +// the same name, it will ask the LazyArchive to load a file.
> +class LazyArchive : public Symbol {
>  public:
> -  Lazy(ArchiveFile *f, const Archive::Symbol s)
> -      : Symbol(LazyKind, s.getName()), file(f), sym(s) {}
> +  LazyArchive(ArchiveFile *f, const Archive::Symbol s)
> +      : Symbol(LazyArchiveKind, s.getName()), file(f), sym(s) {}
>
> -  static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
> +  static bool classof(const Symbol *s) { return s->kind() ==
> LazyArchiveKind; }
>
>    MemoryBufferRef getMemberBuffer();
>
>    ArchiveFile *file;
> -
> -private:
> -  friend SymbolTable;
> -
> -private:
>    const Archive::Symbol sym;
>  };
>
> +class LazyObject : public Symbol {
> +public:
> +  LazyObject(LazyObjFile *f, StringRef n)
> +      : Symbol(LazyObjectKind, n), file(f) {}
> +  static bool classof(const Symbol *s) { return s->kind() ==
> LazyObjectKind; }
> +  LazyObjFile *file;
> +};
> +
>  // Undefined symbols.
>  class Undefined : public Symbol {
>  public:
> @@ -381,7 +389,8 @@ inline uint64_t Defined::getRVA() {
>      return cast<DefinedCommon>(this)->getRVA();
>    case DefinedRegularKind:
>      return cast<DefinedRegular>(this)->getRVA();
> -  case LazyKind:
> +  case LazyArchiveKind:
> +  case LazyObjectKind:
>    case UndefinedKind:
>      llvm_unreachable("Cannot get the address for an undefined symbol.");
>    }
> @@ -404,7 +413,8 @@ inline Chunk *Defined::getChunk() {
>      return cast<DefinedLocalImport>(this)->getChunk();
>    case DefinedCommonKind:
>      return cast<DefinedCommon>(this)->getChunk();
> -  case LazyKind:
> +  case LazyArchiveKind:
> +  case LazyObjectKind:
>    case UndefinedKind:
>      llvm_unreachable("Cannot get the chunk of an undefined symbol.");
>    }
> @@ -419,11 +429,12 @@ union SymbolUnion {
>    alignas(DefinedCommon) char b[sizeof(DefinedCommon)];
>    alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)];
>    alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)];
> -  alignas(Lazy) char e[sizeof(Lazy)];
> +  alignas(LazyArchive) char e[sizeof(LazyArchive)];
>    alignas(Undefined) char f[sizeof(Undefined)];
>    alignas(DefinedImportData) char g[sizeof(DefinedImportData)];
>    alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)];
>    alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)];
> +  alignas(LazyObject) char j[sizeof(LazyObject)];
>  };
>
>  template <typename T, typename... ArgT>
>
> Modified: lld/trunk/COFF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=370487&r1=370486&r2=370487&view=diff
>
> ==============================================================================
> --- lld/trunk/COFF/Writer.cpp (original)
> +++ lld/trunk/COFF/Writer.cpp Fri Aug 30 09:50:10 2019
> @@ -1519,7 +1519,8 @@ static void maybeAddAddressTakenFunction
>      // Absolute is never code, synthetic generally isn't and usually isn't
>      // determinable.
>      break;
> -  case Symbol::LazyKind:
> +  case Symbol::LazyArchiveKind:
> +  case Symbol::LazyObjectKind:
>    case Symbol::UndefinedKind:
>      // Undefined symbols resolve to zero, so they don't have an RVA. Lazy
>      // symbols shouldn't have relocations.
>
> Added: lld/trunk/test/COFF/Inputs/start-lib1.ll
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/start-lib1.ll?rev=370487&view=auto
>
> ==============================================================================
> --- lld/trunk/test/COFF/Inputs/start-lib1.ll (added)
> +++ lld/trunk/test/COFF/Inputs/start-lib1.ll Fri Aug 30 09:50:10 2019
> @@ -0,0 +1,13 @@
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc"
> +
> +declare i32 @bar()
> +
> +define i32 @foo() {
> +  %1 = call i32 () @bar()
> +  %2 = add i32 %1, 1
> +  ret i32 %2
> +}
> +
> +!llvm.linker.options = !{!0}
> +!0 = !{!"/INCLUDE:foo"}
>
> Added: lld/trunk/test/COFF/Inputs/start-lib2.ll
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/start-lib2.ll?rev=370487&view=auto
>
> ==============================================================================
> --- lld/trunk/test/COFF/Inputs/start-lib2.ll (added)
> +++ lld/trunk/test/COFF/Inputs/start-lib2.ll Fri Aug 30 09:50:10 2019
> @@ -0,0 +1,9 @@
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc"
> +
> +define i32 @bar() {
> +  ret i32 1
> +}
> +
> +!llvm.linker.options = !{!0}
> +!0 = !{!"/INCLUDE:bar"}
>
> Added: lld/trunk/test/COFF/start-lib-cmd-diagnostics.ll
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/start-lib-cmd-diagnostics.ll?rev=370487&view=auto
>
> ==============================================================================
> --- lld/trunk/test/COFF/start-lib-cmd-diagnostics.ll (added)
> +++ lld/trunk/test/COFF/start-lib-cmd-diagnostics.ll Fri Aug 30 09:50:10
> 2019
> @@ -0,0 +1,19 @@
> +; REQUIRES: x86
> +;
> +; We need an input file to lld, so create one.
> +; RUN: llc -filetype=obj %s -o %t.obj
> +
> +; RUN: not lld-link %t.obj -end-lib 2>&1 \
> +; RUN:     | FileCheck --check-prefix=STRAY_END %s
> +; STRAY_END: stray -end-lib
> +
> +; RUN: not lld-link -start-lib -start-lib %t.obj 2>&1 \
> +; RUN:     | FileCheck --check-prefix=NESTED_START %s
> +; NESTED_START: nested -start-lib
> +
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc"
> +
> +define void @main() {
> +  ret void
> +}
>
> Added: lld/trunk/test/COFF/start-lib.ll
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/start-lib.ll?rev=370487&view=auto
>
> ==============================================================================
> --- lld/trunk/test/COFF/start-lib.ll (added)
> +++ lld/trunk/test/COFF/start-lib.ll Fri Aug 30 09:50:10 2019
> @@ -0,0 +1,43 @@
> +; REQUIRES: x86
> +;
> +; RUN: llc -filetype=obj %s -o %t.obj
> +; RUN: llc -filetype=obj %p/Inputs/start-lib1.ll -o %t1.obj
> +; RUN: llc -filetype=obj %p/Inputs/start-lib2.ll -o %t2.obj
> +; RUN: opt -thinlto-bc %s -o %t.bc
> +; RUN: opt -thinlto-bc %p/Inputs/start-lib1.ll -o %t1.bc
> +; RUN: opt -thinlto-bc %p/Inputs/start-lib2.ll -o %t2.bc
> +;
> +; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.map \
> +; RUN:     %t.obj %t1.obj %t2.obj
> +; RUN: FileCheck --check-prefix=TEST1 %s < %t1.map
> +; RUN: lld-link -out:%t1.exe -entry:main -opt:noref
> -lldmap:%t1.thinlto.map \
> +; RUN:     %t.bc %t1.bc %t2.bc
> +; RUN: FileCheck --check-prefix=TEST1 %s < %t1.thinlto.map
> +; TEST1: foo
> +; TEST1: bar
> +;
> +; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.map \
> +; RUN:     %t.obj -start-lib %t1.obj -end-lib %t2.obj
> +; RUN: FileCheck --check-prefix=TEST2 %s < %t2.map
> +; RUN: lld-link -out:%t2.exe -entry:main -opt:noref
> -lldmap:%t2.thinlto.map \
> +; RUN:     %t.bc -start-lib %t1.bc -end-lib %t2.bc
> +; RUN: FileCheck --check-prefix=TEST2 %s < %t2.thinlto.map
> +; TEST2-NOT: Name: foo
> +; TEST2: bar
> +; TEST2-NOT: Name: foo
> +;
> +; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.map \
> +; RUN:     %t.obj -start-lib %t1.obj %t2.obj
> +; RUN: FileCheck --check-prefix=TEST3 %s < %t3.map
> +; RUN: lld-link -out:%t3.exe -entry:main -opt:noref
> -lldmap:%t3.thinlto.map \
> +; RUN:     %t.bc -start-lib %t1.bc %t2.bc
> +; RUN: FileCheck --check-prefix=TEST3 %s < %t3.thinlto.map
> +; TEST3-NOT: foo
> +; TEST3-NOT: bar
> +
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc"
> +
> +define void @main() {
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190830/7849d165/attachment.html>


More information about the llvm-commits mailing list