[lld] fd9962e - [COFF] Add vfsoverlay flag
Alex Brachet via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 11 14:32:11 PDT 2022
Author: Alex Brachet
Date: 2022-07-11T21:31:01Z
New Revision: fd9962e75d8935a042f1ae1e1647e115f4a632fb
URL: https://github.com/llvm/llvm-project/commit/fd9962e75d8935a042f1ae1e1647e115f4a632fb
DIFF: https://github.com/llvm/llvm-project/commit/fd9962e75d8935a042f1ae1e1647e115f4a632fb.diff
LOG: [COFF] Add vfsoverlay flag
This patch adds a new flag vfsoverlay similar to clang’s
ivfsoverlay flag. This is helpful when compiling on case
sensitive file systems when cross compiling to Windows.
Particularly when compiling third party code containing
\#pragma comment(“linker”, “/defaultlib:...”) which
can’t be easily changed.
Differential Revision: https://reviews.llvm.org/D125800
Added:
lld/test/COFF/vfsoverlay.test
Modified:
lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Options.td
Removed:
################################################################################
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 8edb545cd653e..dd089f5ab6714 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/CachePruning.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <cstdint>
#include <map>
#include <set>
@@ -238,6 +239,9 @@ struct Configuration {
// Used for /print-symbol-order:
StringRef printSymbolOrder;
+ // Used for /vfsoverlay:
+ std::unique_ptr<llvm::vfs::FileSystem> vfs;
+
uint64_t align = 4096;
uint64_t imageBase = -1;
uint64_t fileAlign = 512;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index ffa900d42f2de..155e4ca6ee3fe 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -436,17 +436,26 @@ void LinkerDriver::parseDirectives(InputFile *file) {
// Find file from search paths. You can omit ".obj", this function takes
// care of that. Note that the returned path is not guaranteed to exist.
StringRef LinkerDriver::doFindFile(StringRef filename) {
+ auto getFilename = [](StringRef filename) -> StringRef {
+ if (config->vfs)
+ if (auto statOrErr = config->vfs->status(filename))
+ return saver().save(statOrErr->getName());
+ return filename;
+ };
+
bool hasPathSep = (filename.find_first_of("/\\") != StringRef::npos);
if (hasPathSep)
- return filename;
+ return getFilename(filename);
bool hasExt = filename.contains('.');
for (StringRef dir : searchPaths) {
SmallString<128> path = dir;
sys::path::append(path, filename);
+ path = SmallString<128>{getFilename(path.str())};
if (sys::fs::exists(path.str()))
return saver().save(path.str());
if (!hasExt) {
path.append(".obj");
+ path = SmallString<128>{getFilename(path.str())};
if (sys::fs::exists(path.str()))
return saver().save(path.str());
}
@@ -1349,6 +1358,28 @@ Optional<std::string> getReproduceFile(const opt::InputArgList &args) {
return None;
}
+static std::unique_ptr<llvm::vfs::FileSystem>
+getVFS(const opt::InputArgList &args) {
+ using namespace llvm::vfs;
+
+ const opt::Arg *arg = args.getLastArg(OPT_vfsoverlay);
+ if (!arg)
+ return nullptr;
+
+ auto bufOrErr = llvm::MemoryBuffer::getFile(arg->getValue());
+ if (!bufOrErr) {
+ checkError(errorCodeToError(bufOrErr.getError()));
+ return nullptr;
+ }
+
+ if (auto ret = vfs::getVFSFromYAML(std::move(*bufOrErr), /*DiagHandler*/ nullptr,
+ arg->getValue()))
+ return ret;
+
+ error("Invalid vfs overlay");
+ return nullptr;
+}
+
void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
ScopedTimer rootTimer(ctx.rootTimer);
@@ -1390,6 +1421,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
errorHandler().errorLimit = n;
}
+ config->vfs = getVFS(args);
+
// Handle /help
if (args.hasArg(OPT_help)) {
printHelp(argsArr[0]);
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 9f29ea0d523a7..5135f4ea34af6 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -278,6 +278,8 @@ def print_symbol_order: P<
"/call-graph-profile-sort into the specified file">;
def wrap : P_priv<"wrap">;
+def vfsoverlay : P<"vfsoverlay", "Path to a vfsoverlay yaml file to optionally look for /defaultlib's in">;
+
// Flags for debugging
def lldmap : F<"lldmap">;
def lldmap_file : P_priv<"lldmap">;
diff --git a/lld/test/COFF/vfsoverlay.test b/lld/test/COFF/vfsoverlay.test
new file mode 100644
index 0000000000000..0168ccbce1d29
--- /dev/null
+++ b/lld/test/COFF/vfsoverlay.test
@@ -0,0 +1,33 @@
+# RUN: rm -rf %t
+# RUN: split-file %s %t
+# RUN: cp %p/Inputs/std64.lib %t/std64.lib
+# RUN: sed -e "s|REPLACE|%/t/std64.lib|g" %t/overlay.yaml.in > %t/overlay.yaml
+
+# RUN: lld-link %S/Inputs/hello64.obj /libpath:/noexist /out:%t.exe /entry:main /defaultlib:notstd64 /vfsoverlay:%t/overlay.yaml
+
+# RUN: not lld-link %S/Inputs/hello64.obj /libpath:/noexist /out:%t.exe /entry:main /defaultlib:notstd64 /vfsoverlay:noexist 2>&1 \
+# RUN: | FileCheck %s
+# CHECK: error: No such file or directory
+
+# RUN: sed -e "s|{|bad|g" %t/overlay.yaml > %t/badoverlay.yaml
+# RUN: not lld-link %S/Inputs/hello64.obj /libpath:/noexist /out:%t.exe /entry:main /defaultlib:notstd64 /vfsoverlay:%t/badoverlay.yaml 2>&1 \
+# RUN: | FileCheck %s --check-prefix=BAD-OVERLAY
+# BAD-OVERLAY: error: Invalid vfs overlay
+
+#--- overlay.yaml.in
+{
+ 'version': 0,
+ 'roots' : [
+ {
+ 'name': '/noexist',
+ 'type': 'directory',
+ 'contents': [
+ {
+ 'name': 'notstd64.lib',
+ 'type': 'file',
+ 'external-contents': 'REPLACE'
+ }
+ ]
+ }
+ ]
+}
More information about the llvm-commits
mailing list