mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-25 14:50:26 +00:00
[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
This commit is contained in:
parent
c179bcc151
commit
fd9962e75d
@ -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;
|
||||
|
@ -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]);
|
||||
|
@ -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">;
|
||||
|
33
lld/test/COFF/vfsoverlay.test
Normal file
33
lld/test/COFF/vfsoverlay.test
Normal file
@ -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'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user