From 00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 10 Dec 2014 00:33:00 +0000 Subject: Re-commit r223330: Rewrite InputGraph's Group llvm-svn: 223867 --- lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 32 ++++++++++++++++++++++ .../ReaderWriter/PECOFF/PECOFFLinkingContext.cpp | 19 ++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) (limited to 'lld/lib/ReaderWriter') diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index 3e91e4a56b3..b129c033740 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Config/config.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Host.h" #include "llvm/Support/MachO.h" #include "llvm/Support/Path.h" @@ -923,4 +924,35 @@ bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left, return true; } +static File *getFirstFile(const std::unique_ptr &elem) { + FileNode *e = dyn_cast(const_cast(elem.get())); + if (!e || e->files().empty()) + return nullptr; + return e->files()[0].get(); +} + +static bool isLibrary(const std::unique_ptr &elem) { + File *f = getFirstFile(elem); + return f && (isa(f) || isa(f)); +} + +// The darwin linker processes input files in two phases. The first phase +// links in all object (.o) files in command line order. The second phase +// links in libraries in command line order. +// In this function we reorder the input files so that all the object files +// comes before any library file. We also make a group for the library files +// so that the Resolver will reiterate over the libraries as long as we find +// new undefines from libraries. +void MachOLinkingContext::maybeSortInputFiles() { + std::vector> &elements + = getInputGraph().inputElements(); + std::stable_sort(elements.begin(), elements.end(), + [](const std::unique_ptr &a, + const std::unique_ptr &b) { + return !isLibrary(a) && isLibrary(b); + }); + size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary); + elements.push_back(llvm::make_unique(numLibs)); +} + } // end namespace lld diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp index ae236f475ba..7dc64d3fd5e 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -87,6 +87,23 @@ std::unique_ptr PECOFFLinkingContext::createUndefinedSymbolFile() const { ""); } +void PECOFFLinkingContext::addLibraryFile(std::unique_ptr file) { + GroupEnd *currentGroupEnd; + int pos = -1; + std::vector> &elements + = getInputGraph().inputElements(); + for (int i = 0, e = elements.size(); i < e; ++i) { + if ((currentGroupEnd = dyn_cast(elements[i].get()))) { + pos = i; + break; + } + } + assert(pos >= 0); + elements.insert(elements.begin() + pos, std::move(file)); + elements[pos + 1] = llvm::make_unique( + currentGroupEnd->getSize() + 1); +} + bool PECOFFLinkingContext::createImplicitFiles( std::vector> &) { // Create a file for __ImageBase. @@ -109,7 +126,7 @@ bool PECOFFLinkingContext::createImplicitFiles( auto exportNode = llvm::make_unique(""); exportNode->appendInputFile( llvm::make_unique(*this, syms)); - getLibraryGroup()->addFile(std::move(exportNode)); + addLibraryFile(std::move(exportNode)); // Create a file for the entry point function. getEntryNode()->appendInputFile( -- cgit v1.2.3