diff options
| author | Rui Ueyama <ruiu@google.com> | 2014-12-10 00:33:00 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2014-12-10 00:33:00 +0000 |
| commit | 00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79 (patch) | |
| tree | ecd3def36561bcc8ade871e50674266fa47c7611 /lld/lib/ReaderWriter | |
| parent | f3108ce3e8fa2f6440810512d53d84ed869569fb (diff) | |
| download | bcm5719-llvm-00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79.tar.gz bcm5719-llvm-00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79.zip | |
Re-commit r223330: Rewrite InputGraph's Group
llvm-svn: 223867
Diffstat (limited to 'lld/lib/ReaderWriter')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 32 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp | 19 |
2 files changed, 50 insertions, 1 deletions
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<InputElement> &elem) { + FileNode *e = dyn_cast<FileNode>(const_cast<InputElement *>(elem.get())); + if (!e || e->files().empty()) + return nullptr; + return e->files()[0].get(); +} + +static bool isLibrary(const std::unique_ptr<InputElement> &elem) { + File *f = getFirstFile(elem); + return f && (isa<SharedLibraryFile>(f) || isa<ArchiveLibraryFile>(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<std::unique_ptr<InputElement>> &elements + = getInputGraph().inputElements(); + std::stable_sort(elements.begin(), elements.end(), + [](const std::unique_ptr<InputElement> &a, + const std::unique_ptr<InputElement> &b) { + return !isLibrary(a) && isLibrary(b); + }); + size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary); + elements.push_back(llvm::make_unique<GroupEnd>(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<File> PECOFFLinkingContext::createUndefinedSymbolFile() const { "<command line option /include>"); } +void PECOFFLinkingContext::addLibraryFile(std::unique_ptr<FileNode> file) { + GroupEnd *currentGroupEnd; + int pos = -1; + std::vector<std::unique_ptr<InputElement>> &elements + = getInputGraph().inputElements(); + for (int i = 0, e = elements.size(); i < e; ++i) { + if ((currentGroupEnd = dyn_cast<GroupEnd>(elements[i].get()))) { + pos = i; + break; + } + } + assert(pos >= 0); + elements.insert(elements.begin() + pos, std::move(file)); + elements[pos + 1] = llvm::make_unique<GroupEnd>( + currentGroupEnd->getSize() + 1); +} + bool PECOFFLinkingContext::createImplicitFiles( std::vector<std::unique_ptr<File>> &) { // Create a file for __ImageBase. @@ -109,7 +126,7 @@ bool PECOFFLinkingContext::createImplicitFiles( auto exportNode = llvm::make_unique<SimpleFileNode>("<export>"); exportNode->appendInputFile( llvm::make_unique<pecoff::ExportedSymbolRenameFile>(*this, syms)); - getLibraryGroup()->addFile(std::move(exportNode)); + addLibraryFile(std::move(exportNode)); // Create a file for the entry point function. getEntryNode()->appendInputFile( |

