summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2018-01-29 21:50:53 +0000
committerRui Ueyama <ruiu@google.com>2018-01-29 21:50:53 +0000
commitb6d3a93594d2c136f606b6a6f3ba5e8b6d4e419d (patch)
treea733454a5f9d05be3836486ddb5fc65ee3b3eeea
parent0c55bda4fb4fea61bdfc9a055b7c55b72cbbdb03 (diff)
downloadbcm5719-llvm-b6d3a93594d2c136f606b6a6f3ba5e8b6d4e419d.tar.gz
bcm5719-llvm-b6d3a93594d2c136f606b6a6f3ba5e8b6d4e419d.zip
Warn on nonexistent comdat sections in an /order file.
I didn't implement the feature in the original patch because I didn't come up with an idea to do that easily and efficiently. Turned out that that is actually easy to implement. In this patch, we collect comdat sections before gc is run and warn on nonexistent symbols in an order file. Differential Revision: https://reviews.llvm.org/D42658 llvm-svn: 323699
-rw-r--r--lld/COFF/Driver.cpp23
-rw-r--r--lld/test/COFF/order.test12
2 files changed, 30 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());
diff --git a/lld/test/COFF/order.test b/lld/test/COFF/order.test
index 25df87d7dba..a01f820e784 100644
--- a/lld/test/COFF/order.test
+++ b/lld/test/COFF/order.test
@@ -24,6 +24,18 @@
# DEFAULT: fn4
# DEFAULT: fn1
+# RUN: echo fn1 > %t2.order
+# RUN: echo fn2 >> %t2.order
+# RUN: echo fn3 >> %t2.order
+# RUN: echo fn4 >> %t2.order
+# RUN: echo foo >> %t2.order
+# RUN: lld-link -entry:fn1 -subsystem:console -debug %t1.obj %t2.obj \
+# RUN: -out:%t.exe -order:@%t2.order 2>&1 | FileCheck -check-prefix=WARN %s
+# WARN: warning: /order:{{.*}} missing symbol: foo
+# WARN-NOT: f2
+# WARN-NOT: f3
+# WARN-NOT: f4
+
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
OpenPOWER on IntegriCloud