summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-12-10 00:33:00 +0000
committerRui Ueyama <ruiu@google.com>2014-12-10 00:33:00 +0000
commit00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79 (patch)
treeecd3def36561bcc8ade871e50674266fa47c7611 /lld/lib/ReaderWriter
parentf3108ce3e8fa2f6440810512d53d84ed869569fb (diff)
downloadbcm5719-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.cpp32
-rw-r--r--lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp19
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(
OpenPOWER on IntegriCloud