summaryrefslogtreecommitdiffstats
path: root/lld/COFF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/Driver.cpp')
-rw-r--r--lld/COFF/Driver.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 1b86fe96a31..068074a7b98 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -768,6 +768,13 @@ static void parseOrderFile(StringRef Arg) {
return;
}
+ // Get a list of all comdat sections for error checking.
+ DenseSet<StringRef> Set;
+ for (Chunk *C : Symtab->getChunks())
+ if (auto *Sec = dyn_cast<SectionChunk>(C))
+ if (Sec->Sym)
+ Set.insert(Sec->Sym->getName());
+
// Open a file.
StringRef Path = Arg.substr(1);
std::unique_ptr<MemoryBuffer> MB = CHECK(
@@ -780,7 +787,11 @@ static void parseOrderFile(StringRef Arg) {
for (std::string S : args::getLines(MB->getMemBufferRef())) {
if (Config->Machine == I386 && !isDecorated(S))
S = "_" + S;
- Config->Order[S] = INT_MIN + Config->Order.size();
+
+ if (Set.count(S) == 0)
+ warn("/order:" + Arg + ": missing symbol: " + S);
+ else
+ Config->Order[S] = INT_MIN + Config->Order.size();
}
}
@@ -1188,10 +1199,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
}
}
- // Handle /order
- if (auto *Arg = Args.getLastArg(OPT_order))
- parseOrderFile(Arg->getValue());
-
// Handle /export
for (auto *Arg : Args.filtered(OPT_export)) {
Export E = parseExport(Arg->getValue());
@@ -1391,6 +1398,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (Config->Manifest == Configuration::SideBySide)
createSideBySideManifest();
+ // Handle /order. We want to do this at this moment because we
+ // need a complete list of comdat sections to warn on nonexistent
+ // functions.
+ if (auto *Arg = Args.getLastArg(OPT_order))
+ parseOrderFile(Arg->getValue());
+
// Identify unreferenced COMDAT sections.
if (Config->DoGC)
markLive(Symtab->getChunks());
OpenPOWER on IntegriCloud