[lld] r334552 - Fix /WholeArchive bug.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 12 14:47:31 PDT 2018
Author: ruiu
Date: Tue Jun 12 14:47:31 2018
New Revision: 334552
URL: http://llvm.org/viewvc/llvm-project?rev=334552&view=rev
Log:
Fix /WholeArchive bug.
`lld-link foo.lib /wholearchive:foo.lib` should work the same way as
`lld-link /wholearchive:foo.lib foo.lib`. Previously, /wholearchive in
the former case was ignored.
Differential Revision: https://reviews.llvm.org/D47565
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/test/COFF/wholearchive.s
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=334552&r1=334551&r2=334552&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Tue Jun 12 14:47:31 2018
@@ -332,13 +332,24 @@ StringRef LinkerDriver::doFindFile(Strin
return Filename;
}
+static Optional<sys::fs::UniqueID> getUniqueID(StringRef Path) {
+ sys::fs::UniqueID Ret;
+ if (sys::fs::getUniqueID(Path, Ret))
+ return None;
+ return Ret;
+}
+
// Resolves a file path. This never returns the same path
// (in that case, it returns None).
Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
StringRef Path = doFindFile(Filename);
- bool Seen = !VisitedFiles.insert(Path.lower()).second;
- if (Seen)
- return None;
+
+ if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) {
+ bool Seen = !VisitedFiles.insert(*ID).second;
+ if (Seen)
+ return None;
+ }
+
if (Path.endswith_lower(".lib"))
VisitedLibs.insert(sys::path::filename(Path));
return Path;
@@ -361,11 +372,14 @@ Optional<StringRef> LinkerDriver::findLi
return None;
if (!VisitedLibs.insert(Filename.lower()).second)
return None;
+
StringRef Path = doFindLib(Filename);
if (Config->NoDefaultLibs.count(Path))
return None;
- if (!VisitedFiles.insert(Path.lower()).second)
- return None;
+
+ if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path))
+ if (!VisitedFiles.insert(*ID).second)
+ return None;
return Path;
}
@@ -1231,22 +1245,29 @@ void LinkerDriver::link(ArrayRef<const c
if (errorCount())
return;
- bool WholeArchiveFlag = Args.hasArg(OPT_wholearchive_flag);
+ std::set<sys::fs::UniqueID> WholeArchives;
+ for (auto *Arg : Args.filtered(OPT_wholearchive_file))
+ if (Optional<sys::fs::UniqueID> ID = getUniqueID(Arg->getValue()))
+ WholeArchives.insert(*ID);
+
+ // A predicate returning true if a given path is an argument for
+ // /wholearchive:, or /wholearchive is enabled globally.
+ // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj"
+ // needs to be handled as "/wholearchive:foo.obj foo.obj".
+ auto IsWholeArchive = [&](StringRef Path) -> bool {
+ if (Args.hasArg(OPT_wholearchive_flag))
+ return true;
+ if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path))
+ return WholeArchives.count(*ID);
+ return false;
+ };
+
// Create a list of input files. Files can be given as arguments
// for /defaultlib option.
- std::vector<MemoryBufferRef> MBs;
- for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) {
- switch (Arg->getOption().getID()) {
- case OPT_INPUT:
- if (Optional<StringRef> Path = findFile(Arg->getValue()))
- enqueuePath(*Path, WholeArchiveFlag);
- break;
- case OPT_wholearchive_file:
- if (Optional<StringRef> Path = findFile(Arg->getValue()))
- enqueuePath(*Path, true);
- break;
- }
- }
+ for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file))
+ if (Optional<StringRef> Path = findFile(Arg->getValue()))
+ enqueuePath(*Path, IsWholeArchive(Arg->getValue()));
+
for (auto *Arg : Args.filtered(OPT_defaultlib))
if (Optional<StringRef> Path = findLib(Arg->getValue()))
enqueuePath(*Path, false);
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=334552&r1=334551&r2=334552&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Tue Jun 12 14:47:31 2018
@@ -21,6 +21,7 @@
#include "llvm/Object/COFF.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TarWriter.h"
#include <memory>
#include <set>
@@ -94,7 +95,11 @@ private:
// Library search path. The first element is always "" (current directory).
std::vector<StringRef> SearchPaths;
- std::set<std::string> VisitedFiles;
+
+ // We don't want to add the same file more than once.
+ // Files are uniquified by their filesystem and file number.
+ std::set<llvm::sys::fs::UniqueID> VisitedFiles;
+
std::set<std::string> VisitedLibs;
Symbol *addUndefined(StringRef Sym);
Modified: lld/trunk/test/COFF/wholearchive.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/wholearchive.s?rev=334552&r1=334551&r2=334552&view=diff
==============================================================================
--- lld/trunk/test/COFF/wholearchive.s (original)
+++ lld/trunk/test/COFF/wholearchive.s Tue Jun 12 14:47:31 2018
@@ -10,6 +10,14 @@
# RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive %t.archive.lib -implib:%t.lib
# RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB
+# RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj %t.archive.lib -wholearchive:%t.archive.lib -implib:%t.lib
+# RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB
+
+# RUN: mkdir -p %t.dir
+# RUN: cp %t.archive.lib %t.dir/foo.lib
+# RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj %t.dir/./foo.lib -wholearchive:%t.dir/foo.lib -implib:%t.lib
+# RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB
+
# CHECK-IMPLIB: Symbol: __imp_exportfn3
# CHECK-IMPLIB: Symbol: exportfn3
More information about the llvm-commits
mailing list